@parto-system-design/ui 1.1.11 → 1.1.17

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 (409) hide show
  1. package/dist/components/brand/parto-logo.cjs +130 -0
  2. package/dist/components/brand/parto-logo.cjs.map +1 -0
  3. package/dist/components/brand/parto-logo.d.cts +38 -0
  4. package/dist/components/brand/parto-logo.d.ts +38 -0
  5. package/dist/components/brand/parto-logo.js +108 -0
  6. package/dist/components/brand/parto-logo.js.map +1 -0
  7. package/dist/components/charts/PartoAreaChart.cjs +579 -7
  8. package/dist/components/charts/PartoAreaChart.cjs.map +1 -1
  9. package/dist/components/charts/PartoAreaChart.js +564 -4
  10. package/dist/components/charts/PartoAreaChart.js.map +1 -1
  11. package/dist/components/charts/PartoBarChart.cjs +616 -7
  12. package/dist/components/charts/PartoBarChart.cjs.map +1 -1
  13. package/dist/components/charts/PartoBarChart.js +601 -4
  14. package/dist/components/charts/PartoBarChart.js.map +1 -1
  15. package/dist/components/charts/PartoLineChart.cjs +584 -7
  16. package/dist/components/charts/PartoLineChart.cjs.map +1 -1
  17. package/dist/components/charts/PartoLineChart.js +569 -4
  18. package/dist/components/charts/PartoLineChart.js.map +1 -1
  19. package/dist/components/charts/PartoPieChart.cjs +566 -7
  20. package/dist/components/charts/PartoPieChart.cjs.map +1 -1
  21. package/dist/components/charts/PartoPieChart.js +551 -4
  22. package/dist/components/charts/PartoPieChart.js.map +1 -1
  23. package/dist/components/ui/accordion.cjs +97 -0
  24. package/dist/components/ui/accordion.cjs.map +1 -0
  25. package/dist/components/ui/accordion.d.cts +22 -0
  26. package/dist/components/ui/accordion.d.ts +22 -0
  27. package/dist/components/ui/accordion.js +72 -0
  28. package/dist/components/ui/accordion.js.map +1 -0
  29. package/dist/{chunk-MMC6M35Q.cjs → components/ui/alert-dialog.cjs} +216 -22
  30. package/dist/components/ui/alert-dialog.cjs.map +1 -0
  31. package/dist/components/ui/alert-dialog.d.cts +17 -0
  32. package/dist/components/ui/alert-dialog.d.ts +17 -0
  33. package/dist/{chunk-3QYYPPFJ.js → components/ui/alert-dialog.js} +175 -10
  34. package/dist/components/ui/alert-dialog.js.map +1 -0
  35. package/dist/components/ui/alert-rule-card.cjs +289 -8
  36. package/dist/components/ui/alert-rule-card.cjs.map +1 -1
  37. package/dist/components/ui/alert-rule-card.d.cts +1 -1
  38. package/dist/components/ui/alert-rule-card.d.ts +1 -1
  39. package/dist/components/ui/alert-rule-card.js +271 -4
  40. package/dist/components/ui/alert-rule-card.js.map +1 -1
  41. package/dist/components/ui/alert.cjs +81 -0
  42. package/dist/components/ui/alert.cjs.map +1 -0
  43. package/dist/components/ui/alert.d.cts +11 -0
  44. package/dist/components/ui/alert.d.ts +11 -0
  45. package/dist/components/ui/alert.js +57 -0
  46. package/dist/components/ui/alert.js.map +1 -0
  47. package/dist/components/ui/app-bar.cjs +67 -0
  48. package/dist/components/ui/app-bar.cjs.map +1 -0
  49. package/dist/components/ui/app-bar.d.cts +22 -0
  50. package/dist/components/ui/app-bar.d.ts +22 -0
  51. package/dist/components/ui/app-bar.js +44 -0
  52. package/dist/components/ui/app-bar.js.map +1 -0
  53. package/dist/components/ui/avatar.cjs +66 -14
  54. package/dist/components/ui/avatar.cjs.map +1 -1
  55. package/dist/components/ui/avatar.js +47 -2
  56. package/dist/components/ui/avatar.js.map +1 -1
  57. package/dist/components/ui/badge.cjs +113 -9
  58. package/dist/components/ui/badge.cjs.map +1 -1
  59. package/dist/components/ui/badge.js +96 -2
  60. package/dist/components/ui/badge.js.map +1 -1
  61. package/dist/components/ui/breadcrumb.cjs +100 -0
  62. package/dist/components/ui/breadcrumb.cjs.map +1 -0
  63. package/dist/components/ui/breadcrumb.d.cts +35 -0
  64. package/dist/components/ui/breadcrumb.d.ts +35 -0
  65. package/dist/components/ui/breadcrumb.js +92 -0
  66. package/dist/components/ui/breadcrumb.js.map +1 -0
  67. package/dist/components/ui/button.cjs +304 -11
  68. package/dist/components/ui/button.cjs.map +1 -1
  69. package/dist/components/ui/button.d.cts +1 -1
  70. package/dist/components/ui/button.d.ts +1 -1
  71. package/dist/components/ui/button.js +306 -3
  72. package/dist/components/ui/button.js.map +1 -1
  73. package/dist/components/ui/calendar.cjs +401 -8
  74. package/dist/components/ui/calendar.cjs.map +1 -1
  75. package/dist/components/ui/calendar.js +404 -4
  76. package/dist/components/ui/calendar.js.map +1 -1
  77. package/dist/components/ui/card.cjs +154 -30
  78. package/dist/components/ui/card.cjs.map +1 -1
  79. package/dist/components/ui/card.js +131 -2
  80. package/dist/components/ui/card.js.map +1 -1
  81. package/dist/{chunk-CAJKSTXX.cjs → components/ui/checkbox.cjs} +10 -5
  82. package/dist/components/ui/checkbox.cjs.map +1 -0
  83. package/dist/components/ui/checkbox.d.cts +6 -0
  84. package/dist/components/ui/checkbox.d.ts +6 -0
  85. package/dist/{chunk-5JJSRGJD.js → components/ui/checkbox.js} +9 -4
  86. package/dist/components/ui/checkbox.js.map +1 -0
  87. package/dist/components/ui/concept-card.cjs +728 -11
  88. package/dist/components/ui/concept-card.cjs.map +1 -1
  89. package/dist/components/ui/concept-card.d.cts +2 -2
  90. package/dist/components/ui/concept-card.d.ts +2 -2
  91. package/dist/components/ui/concept-card.js +710 -7
  92. package/dist/components/ui/concept-card.js.map +1 -1
  93. package/dist/components/ui/data-table.cjs +1553 -10
  94. package/dist/components/ui/data-table.cjs.map +1 -1
  95. package/dist/components/ui/data-table.js +1537 -7
  96. package/dist/components/ui/data-table.js.map +1 -1
  97. package/dist/components/ui/dialog.cjs +119 -42
  98. package/dist/components/ui/dialog.cjs.map +1 -1
  99. package/dist/components/ui/dialog.js +92 -2
  100. package/dist/components/ui/dialog.js.map +1 -1
  101. package/dist/components/ui/dropdown-menu.cjs +268 -0
  102. package/dist/components/ui/dropdown-menu.cjs.map +1 -0
  103. package/dist/components/ui/dropdown-menu.d.cts +73 -0
  104. package/dist/components/ui/dropdown-menu.d.ts +73 -0
  105. package/dist/components/ui/dropdown-menu.js +232 -0
  106. package/dist/components/ui/dropdown-menu.js.map +1 -0
  107. package/dist/components/ui/filter-provider.cjs +70 -13
  108. package/dist/components/ui/filter-provider.cjs.map +1 -1
  109. package/dist/components/ui/filter-provider.js +51 -1
  110. package/dist/components/ui/filter-provider.js.map +1 -1
  111. package/dist/components/ui/form.cjs +169 -0
  112. package/dist/components/ui/form.cjs.map +1 -0
  113. package/dist/components/ui/form.d.cts +46 -0
  114. package/dist/components/ui/form.d.ts +46 -0
  115. package/dist/components/ui/form.js +139 -0
  116. package/dist/components/ui/form.js.map +1 -0
  117. package/dist/components/ui/input.cjs +135 -15
  118. package/dist/components/ui/input.cjs.map +1 -1
  119. package/dist/components/ui/input.d.cts +15 -0
  120. package/dist/components/ui/input.d.ts +15 -0
  121. package/dist/components/ui/input.js +116 -3
  122. package/dist/components/ui/input.js.map +1 -1
  123. package/dist/components/ui/iran-province-heat.cjs +328 -5
  124. package/dist/components/ui/iran-province-heat.cjs.map +1 -1
  125. package/dist/components/ui/iran-province-heat.js +312 -2
  126. package/dist/components/ui/iran-province-heat.js.map +1 -1
  127. package/dist/components/ui/label.cjs +52 -0
  128. package/dist/components/ui/label.cjs.map +1 -0
  129. package/dist/components/ui/label.d.cts +10 -0
  130. package/dist/components/ui/label.d.ts +10 -0
  131. package/dist/components/ui/label.js +30 -0
  132. package/dist/components/ui/label.js.map +1 -0
  133. package/dist/components/ui/page-card.cjs +627 -8
  134. package/dist/components/ui/page-card.cjs.map +1 -1
  135. package/dist/components/ui/page-card.d.cts +3 -2
  136. package/dist/components/ui/page-card.d.ts +3 -2
  137. package/dist/components/ui/page-card.js +611 -5
  138. package/dist/components/ui/page-card.js.map +1 -1
  139. package/dist/components/ui/page-header.cjs +299 -0
  140. package/dist/components/ui/page-header.cjs.map +1 -0
  141. package/dist/components/ui/page-header.d.cts +21 -0
  142. package/dist/components/ui/page-header.d.ts +21 -0
  143. package/dist/components/ui/page-header.js +277 -0
  144. package/dist/components/ui/page-header.js.map +1 -0
  145. package/dist/components/ui/password-input.cjs +168 -0
  146. package/dist/components/ui/password-input.cjs.map +1 -0
  147. package/dist/components/ui/password-input.d.cts +48 -0
  148. package/dist/components/ui/password-input.d.ts +48 -0
  149. package/dist/components/ui/password-input.js +146 -0
  150. package/dist/components/ui/password-input.js.map +1 -0
  151. package/dist/components/ui/popover.cjs +51 -18
  152. package/dist/components/ui/popover.cjs.map +1 -1
  153. package/dist/components/ui/popover.js +30 -2
  154. package/dist/components/ui/popover.js.map +1 -1
  155. package/dist/components/ui/progress.cjs +95 -0
  156. package/dist/components/ui/progress.cjs.map +1 -0
  157. package/dist/components/ui/progress.d.cts +18 -0
  158. package/dist/components/ui/progress.d.ts +18 -0
  159. package/dist/components/ui/progress.js +72 -0
  160. package/dist/components/ui/progress.js.map +1 -0
  161. package/dist/components/ui/radio-card.cjs +84 -0
  162. package/dist/components/ui/radio-card.cjs.map +1 -0
  163. package/dist/components/ui/radio-card.d.cts +12 -0
  164. package/dist/components/ui/radio-card.d.ts +12 -0
  165. package/dist/components/ui/radio-card.js +58 -0
  166. package/dist/components/ui/radio-card.js.map +1 -0
  167. package/dist/components/ui/radio-group.cjs +62 -0
  168. package/dist/components/ui/radio-group.cjs.map +1 -0
  169. package/dist/components/ui/radio-group.d.cts +7 -0
  170. package/dist/components/ui/radio-group.d.ts +7 -0
  171. package/dist/components/ui/radio-group.js +38 -0
  172. package/dist/components/ui/radio-group.js.map +1 -0
  173. package/dist/components/ui/saved-query-card.cjs +409 -7
  174. package/dist/components/ui/saved-query-card.cjs.map +1 -1
  175. package/dist/components/ui/saved-query-card.js +394 -4
  176. package/dist/components/ui/saved-query-card.js.map +1 -1
  177. package/dist/components/ui/scroll-area.cjs +79 -0
  178. package/dist/components/ui/scroll-area.cjs.map +1 -0
  179. package/dist/components/ui/scroll-area.d.cts +14 -0
  180. package/dist/components/ui/scroll-area.d.ts +14 -0
  181. package/dist/components/ui/scroll-area.js +56 -0
  182. package/dist/components/ui/scroll-area.js.map +1 -0
  183. package/dist/components/ui/select.cjs +242 -0
  184. package/dist/components/ui/select.cjs.map +1 -0
  185. package/dist/components/ui/select.d.cts +29 -0
  186. package/dist/components/ui/select.d.ts +29 -0
  187. package/dist/components/ui/select.js +210 -0
  188. package/dist/components/ui/select.js.map +1 -0
  189. package/dist/components/ui/separator.cjs +105 -6
  190. package/dist/components/ui/separator.cjs.map +1 -1
  191. package/dist/components/ui/separator.js +87 -2
  192. package/dist/components/ui/separator.js.map +1 -1
  193. package/dist/components/ui/sheet.cjs +134 -38
  194. package/dist/components/ui/sheet.cjs.map +1 -1
  195. package/dist/components/ui/sheet.js +109 -2
  196. package/dist/components/ui/sheet.js.map +1 -1
  197. package/dist/{chunk-D2EBLE2B.cjs → components/ui/skeleton.cjs} +21 -16
  198. package/dist/components/ui/skeleton.cjs.map +1 -0
  199. package/dist/components/ui/skeleton.d.cts +90 -0
  200. package/dist/components/ui/skeleton.d.ts +90 -0
  201. package/dist/{chunk-SB5DSYR5.js → components/ui/skeleton.js} +8 -3
  202. package/dist/components/ui/skeleton.js.map +1 -0
  203. package/dist/components/ui/slider.cjs +129 -0
  204. package/dist/components/ui/slider.cjs.map +1 -0
  205. package/dist/components/ui/slider.d.cts +10 -0
  206. package/dist/components/ui/slider.d.ts +10 -0
  207. package/dist/components/ui/slider.js +107 -0
  208. package/dist/components/ui/slider.js.map +1 -0
  209. package/dist/components/ui/social-platform-badge.cjs +120 -0
  210. package/dist/components/ui/social-platform-badge.cjs.map +1 -0
  211. package/dist/components/ui/social-platform-badge.d.cts +21 -0
  212. package/dist/components/ui/social-platform-badge.d.ts +21 -0
  213. package/dist/components/ui/social-platform-badge.js +97 -0
  214. package/dist/components/ui/social-platform-badge.js.map +1 -0
  215. package/dist/components/ui/sonner.cjs +51 -0
  216. package/dist/components/ui/sonner.cjs.map +1 -0
  217. package/dist/components/ui/sonner.d.cts +13 -0
  218. package/dist/components/ui/sonner.d.ts +13 -0
  219. package/dist/components/ui/sonner.js +45 -0
  220. package/dist/components/ui/sonner.js.map +1 -0
  221. package/dist/components/ui/sparkline.cjs +159 -6
  222. package/dist/components/ui/sparkline.cjs.map +1 -1
  223. package/dist/components/ui/sparkline.js +142 -2
  224. package/dist/components/ui/sparkline.js.map +1 -1
  225. package/dist/components/ui/switch.cjs +96 -0
  226. package/dist/components/ui/switch.cjs.map +1 -0
  227. package/dist/components/ui/switch.d.cts +13 -0
  228. package/dist/components/ui/switch.d.ts +13 -0
  229. package/dist/components/ui/switch.js +73 -0
  230. package/dist/components/ui/switch.js.map +1 -0
  231. package/dist/components/ui/table.cjs +188 -0
  232. package/dist/components/ui/table.cjs.map +1 -0
  233. package/dist/components/ui/table.d.cts +59 -0
  234. package/dist/components/ui/table.d.ts +59 -0
  235. package/dist/components/ui/table.js +178 -0
  236. package/dist/components/ui/table.js.map +1 -0
  237. package/dist/components/ui/tabs.cjs +140 -0
  238. package/dist/components/ui/tabs.cjs.map +1 -0
  239. package/dist/components/ui/tabs.d.cts +21 -0
  240. package/dist/components/ui/tabs.d.ts +21 -0
  241. package/dist/components/ui/tabs.js +115 -0
  242. package/dist/components/ui/tabs.js.map +1 -0
  243. package/dist/components/ui/textarea.cjs +56 -0
  244. package/dist/components/ui/textarea.cjs.map +1 -0
  245. package/dist/components/ui/textarea.d.cts +5 -0
  246. package/dist/components/ui/textarea.d.ts +5 -0
  247. package/dist/components/ui/textarea.js +34 -0
  248. package/dist/components/ui/textarea.js.map +1 -0
  249. package/dist/components/ui/toggle-group.cjs +123 -0
  250. package/dist/components/ui/toggle-group.cjs.map +1 -0
  251. package/dist/components/ui/toggle-group.d.cts +7 -0
  252. package/dist/components/ui/toggle-group.d.ts +7 -0
  253. package/dist/components/ui/toggle-group.js +99 -0
  254. package/dist/components/ui/toggle-group.js.map +1 -0
  255. package/dist/components/ui/tooltip.cjs +77 -18
  256. package/dist/components/ui/tooltip.cjs.map +1 -1
  257. package/dist/components/ui/tooltip.js +56 -2
  258. package/dist/components/ui/tooltip.js.map +1 -1
  259. package/dist/{concept-card-RwPbqJ06.d.cts → concept-card-BXra9mr0.d.cts} +2 -2
  260. package/dist/{concept-card-CcOBb2Nz.d.ts → concept-card-BoJ5gIJD.d.ts} +2 -2
  261. package/dist/hooks/use-hotkey-registry.cjs +201 -14
  262. package/dist/hooks/use-hotkey-registry.cjs.map +1 -1
  263. package/dist/hooks/use-hotkey-registry.js +182 -2
  264. package/dist/hooks/use-hotkey-registry.js.map +1 -1
  265. package/dist/hooks/use-hotkeys.cjs +144 -9
  266. package/dist/hooks/use-hotkeys.cjs.map +1 -1
  267. package/dist/hooks/use-hotkeys.js +126 -1
  268. package/dist/hooks/use-hotkeys.js.map +1 -1
  269. package/dist/{i18n-CAd9wGOr.d.cts → i18n-BfRhV5aw.d.cts} +5 -3
  270. package/dist/{i18n-ArS3mqj0.d.ts → i18n-ewyqbKM-.d.ts} +5 -3
  271. package/dist/index.cjs +21003 -15720
  272. package/dist/index.cjs.map +1 -1
  273. package/dist/index.css +412 -71
  274. package/dist/index.d.cts +82 -490
  275. package/dist/index.d.ts +82 -490
  276. package/dist/index.js +6727 -976
  277. package/dist/index.js.map +1 -1
  278. package/dist/{page-card-CmShVqG-.d.cts → page-card-C9XXXOVr.d.cts} +3 -20
  279. package/dist/{page-card-HBn-cy4J.d.ts → page-card-DAnbez_f.d.ts} +3 -20
  280. package/dist/toggle-group-B8r4LOQw.d.cts +26 -0
  281. package/dist/toggle-group-B8r4LOQw.d.ts +26 -0
  282. package/package.json +132 -2
  283. package/tailwind.config.ts +45 -0
  284. package/dist/chunk-2ACKKPWA.cjs +0 -112
  285. package/dist/chunk-2ACKKPWA.cjs.map +0 -1
  286. package/dist/chunk-2UD3LGVX.cjs +0 -316
  287. package/dist/chunk-2UD3LGVX.cjs.map +0 -1
  288. package/dist/chunk-3QYYPPFJ.js.map +0 -1
  289. package/dist/chunk-4SVQNEVH.js +0 -173
  290. package/dist/chunk-4SVQNEVH.js.map +0 -1
  291. package/dist/chunk-4WONHORR.cjs +0 -152
  292. package/dist/chunk-4WONHORR.cjs.map +0 -1
  293. package/dist/chunk-5HCXH6GS.js +0 -409
  294. package/dist/chunk-5HCXH6GS.js.map +0 -1
  295. package/dist/chunk-5JJSRGJD.js.map +0 -1
  296. package/dist/chunk-5K6E4ZSW.cjs +0 -77
  297. package/dist/chunk-5K6E4ZSW.cjs.map +0 -1
  298. package/dist/chunk-5NY26ULO.js +0 -89
  299. package/dist/chunk-5NY26ULO.js.map +0 -1
  300. package/dist/chunk-7RVPG3LE.cjs +0 -231
  301. package/dist/chunk-7RVPG3LE.cjs.map +0 -1
  302. package/dist/chunk-AYEK3WOM.js +0 -207
  303. package/dist/chunk-AYEK3WOM.js.map +0 -1
  304. package/dist/chunk-BRMBLIQG.js +0 -53
  305. package/dist/chunk-BRMBLIQG.js.map +0 -1
  306. package/dist/chunk-CAJKSTXX.cjs.map +0 -1
  307. package/dist/chunk-CKFWMHQU.js +0 -401
  308. package/dist/chunk-CKFWMHQU.js.map +0 -1
  309. package/dist/chunk-CV3N3HVK.js +0 -672
  310. package/dist/chunk-CV3N3HVK.js.map +0 -1
  311. package/dist/chunk-D2EBLE2B.cjs.map +0 -1
  312. package/dist/chunk-GCZ6YATL.js +0 -940
  313. package/dist/chunk-GCZ6YATL.js.map +0 -1
  314. package/dist/chunk-GKRAZGDI.cjs +0 -84
  315. package/dist/chunk-GKRAZGDI.cjs.map +0 -1
  316. package/dist/chunk-GPYJ66CG.js +0 -45
  317. package/dist/chunk-GPYJ66CG.js.map +0 -1
  318. package/dist/chunk-HF6XU5NI.js +0 -84
  319. package/dist/chunk-HF6XU5NI.js.map +0 -1
  320. package/dist/chunk-HJPDZOMJ.cjs +0 -87
  321. package/dist/chunk-HJPDZOMJ.cjs.map +0 -1
  322. package/dist/chunk-HS3XI3CC.cjs +0 -69
  323. package/dist/chunk-HS3XI3CC.cjs.map +0 -1
  324. package/dist/chunk-HUCC3QH5.cjs +0 -53
  325. package/dist/chunk-HUCC3QH5.cjs.map +0 -1
  326. package/dist/chunk-HYZ6BQPS.cjs +0 -425
  327. package/dist/chunk-HYZ6BQPS.cjs.map +0 -1
  328. package/dist/chunk-ISCSZMYW.cjs +0 -106
  329. package/dist/chunk-ISCSZMYW.cjs.map +0 -1
  330. package/dist/chunk-IXFEFIDO.js +0 -82
  331. package/dist/chunk-IXFEFIDO.js.map +0 -1
  332. package/dist/chunk-JCJLN437.js +0 -108
  333. package/dist/chunk-JCJLN437.js.map +0 -1
  334. package/dist/chunk-JMKNNH63.cjs +0 -982
  335. package/dist/chunk-JMKNNH63.cjs.map +0 -1
  336. package/dist/chunk-JUBHQAA2.js +0 -53
  337. package/dist/chunk-JUBHQAA2.js.map +0 -1
  338. package/dist/chunk-K6G63EED.cjs +0 -41
  339. package/dist/chunk-K6G63EED.cjs.map +0 -1
  340. package/dist/chunk-KCWRCSI7.js +0 -62
  341. package/dist/chunk-KCWRCSI7.js.map +0 -1
  342. package/dist/chunk-KYM7NIJO.cjs +0 -433
  343. package/dist/chunk-KYM7NIJO.cjs.map +0 -1
  344. package/dist/chunk-L2L5CKC2.js +0 -291
  345. package/dist/chunk-L2L5CKC2.js.map +0 -1
  346. package/dist/chunk-M5CHZ5BA.js +0 -124
  347. package/dist/chunk-M5CHZ5BA.js.map +0 -1
  348. package/dist/chunk-MEK4RSGC.js +0 -65
  349. package/dist/chunk-MEK4RSGC.js.map +0 -1
  350. package/dist/chunk-MEKWH3GS.js +0 -89
  351. package/dist/chunk-MEKWH3GS.js.map +0 -1
  352. package/dist/chunk-MFTX2DDQ.js +0 -27
  353. package/dist/chunk-MFTX2DDQ.js.map +0 -1
  354. package/dist/chunk-MMC6M35Q.cjs.map +0 -1
  355. package/dist/chunk-NMH43BDC.js +0 -130
  356. package/dist/chunk-NMH43BDC.js.map +0 -1
  357. package/dist/chunk-NORDUD2T.cjs +0 -135
  358. package/dist/chunk-NORDUD2T.cjs.map +0 -1
  359. package/dist/chunk-NV4JOKWL.cjs +0 -197
  360. package/dist/chunk-NV4JOKWL.cjs.map +0 -1
  361. package/dist/chunk-O2JG7WY5.cjs +0 -121
  362. package/dist/chunk-O2JG7WY5.cjs.map +0 -1
  363. package/dist/chunk-ONO2FTV4.cjs +0 -68
  364. package/dist/chunk-ONO2FTV4.cjs.map +0 -1
  365. package/dist/chunk-OQB6HIUL.cjs +0 -108
  366. package/dist/chunk-OQB6HIUL.cjs.map +0 -1
  367. package/dist/chunk-OS6CMYAS.cjs +0 -79
  368. package/dist/chunk-OS6CMYAS.cjs.map +0 -1
  369. package/dist/chunk-PYURPUTV.js +0 -402
  370. package/dist/chunk-PYURPUTV.js.map +0 -1
  371. package/dist/chunk-RJ3HYZ7S.js +0 -44
  372. package/dist/chunk-RJ3HYZ7S.js.map +0 -1
  373. package/dist/chunk-RZNRIOLT.js +0 -128
  374. package/dist/chunk-RZNRIOLT.js.map +0 -1
  375. package/dist/chunk-S3T2L6NA.js +0 -38
  376. package/dist/chunk-S3T2L6NA.js.map +0 -1
  377. package/dist/chunk-S5IPJQZ3.cjs +0 -161
  378. package/dist/chunk-S5IPJQZ3.cjs.map +0 -1
  379. package/dist/chunk-SB5DSYR5.js.map +0 -1
  380. package/dist/chunk-SFXV2DUH.js +0 -106
  381. package/dist/chunk-SFXV2DUH.js.map +0 -1
  382. package/dist/chunk-SXEPGD4Z.cjs +0 -152
  383. package/dist/chunk-SXEPGD4Z.cjs.map +0 -1
  384. package/dist/chunk-SXWSOU3Y.js +0 -89
  385. package/dist/chunk-SXWSOU3Y.js.map +0 -1
  386. package/dist/chunk-SZMVOHT7.cjs +0 -107
  387. package/dist/chunk-SZMVOHT7.cjs.map +0 -1
  388. package/dist/chunk-TWJXOV4C.js +0 -145
  389. package/dist/chunk-TWJXOV4C.js.map +0 -1
  390. package/dist/chunk-U3ADRIVO.cjs +0 -434
  391. package/dist/chunk-U3ADRIVO.cjs.map +0 -1
  392. package/dist/chunk-U5FLLCGC.cjs +0 -151
  393. package/dist/chunk-U5FLLCGC.cjs.map +0 -1
  394. package/dist/chunk-UOZN45G4.cjs +0 -130
  395. package/dist/chunk-UOZN45G4.cjs.map +0 -1
  396. package/dist/chunk-VHLDOG74.cjs +0 -167
  397. package/dist/chunk-VHLDOG74.cjs.map +0 -1
  398. package/dist/chunk-YC5KLN6I.js +0 -139
  399. package/dist/chunk-YC5KLN6I.js.map +0 -1
  400. package/dist/chunk-YENXXYUV.cjs +0 -111
  401. package/dist/chunk-YENXXYUV.cjs.map +0 -1
  402. package/dist/chunk-YFQWC2PW.js +0 -113
  403. package/dist/chunk-YFQWC2PW.js.map +0 -1
  404. package/dist/chunk-Z2TY4A75.cjs +0 -700
  405. package/dist/chunk-Z2TY4A75.cjs.map +0 -1
  406. package/dist/chunk-Z56O7UEU.cjs +0 -136
  407. package/dist/chunk-Z56O7UEU.cjs.map +0 -1
  408. package/dist/chunk-ZBZDR4ZC.js +0 -106
  409. package/dist/chunk-ZBZDR4ZC.js.map +0 -1
@@ -0,0 +1,178 @@
1
+ 'use client';
2
+ import { clsx } from 'clsx';
3
+ import { twMerge } from 'tailwind-merge';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ function cn(...inputs) {
7
+ return twMerge(clsx(inputs));
8
+ }
9
+ function Table({
10
+ className,
11
+ size = "md",
12
+ striped = false,
13
+ bordered = false,
14
+ stickyHeader = false,
15
+ ...props
16
+ }) {
17
+ return /* @__PURE__ */ jsx("div", { "data-slot": "table-container", className: "relative w-full overflow-x-auto", children: /* @__PURE__ */ jsx(
18
+ "table",
19
+ {
20
+ "data-slot": "table",
21
+ "data-size": size,
22
+ "data-striped": striped || void 0,
23
+ "data-bordered": bordered || void 0,
24
+ "data-sticky-header": stickyHeader || void 0,
25
+ className: cn("w-full caption-bottom", className),
26
+ ...props
27
+ }
28
+ ) });
29
+ }
30
+ function TableHeader({ className, ...props }) {
31
+ return /* @__PURE__ */ jsx(
32
+ "thead",
33
+ {
34
+ "data-slot": "table-header",
35
+ className: cn(
36
+ // 1.1.16 — internal row dividers use --border-muted (subtle), same
37
+ // rationale as Card. The page-level rule of thumb: borders that
38
+ // separate sections of one surface should whisper, not shout.
39
+ "[&_tr]:border-b [&_tr]:border-muted bg-surface-75",
40
+ "[[data-sticky-header]_&]:sticky [[data-sticky-header]_&]:top-0 [[data-sticky-header]_&]:z-[9] [[data-sticky-header]_&]:bg-surface-75",
41
+ className
42
+ ),
43
+ ...props
44
+ }
45
+ );
46
+ }
47
+ function TableBody({ className, ...props }) {
48
+ return /* @__PURE__ */ jsx(
49
+ "tbody",
50
+ {
51
+ "data-slot": "table-body",
52
+ className: cn(
53
+ "[&_tr:last-child]:border-0",
54
+ "[[data-striped]_&_tr:nth-child(even)]:bg-surface-75 [[data-striped]_&_tr:nth-child(even):hover]:bg-surface-200",
55
+ className
56
+ ),
57
+ ...props
58
+ }
59
+ );
60
+ }
61
+ function TableFooter({ className, ...props }) {
62
+ return /* @__PURE__ */ jsx(
63
+ "tfoot",
64
+ {
65
+ "data-slot": "table-footer",
66
+ className: cn("bg-muted/50 border-t font-medium [&>tr]:last:border-b-0", className),
67
+ ...props
68
+ }
69
+ );
70
+ }
71
+ function TableRow({ className, ...props }) {
72
+ return /* @__PURE__ */ jsx(
73
+ "tr",
74
+ {
75
+ "data-slot": "table-row",
76
+ className: cn(
77
+ "hover:bg-surface-200 data-[state=selected]:bg-selection border-b border-muted transition-colors",
78
+ className
79
+ ),
80
+ ...props
81
+ }
82
+ );
83
+ }
84
+ function TableHead({ className, sortDirection, ...props }) {
85
+ const ariaSort = sortDirection === "asc" ? "ascending" : sortDirection === "desc" ? "descending" : sortDirection === "none" ? "none" : void 0;
86
+ return /* @__PURE__ */ jsx(
87
+ "th",
88
+ {
89
+ "data-slot": "table-head",
90
+ "aria-sort": ariaSort,
91
+ className: cn(
92
+ "text-foreground-lighter text-start align-middle font-semibold whitespace-nowrap [&:has([role=checkbox])]:pe-0 [&>[role=checkbox]]:translate-y-[2px]",
93
+ // Size variants (inherited from parent table)
94
+ "[[data-size=sm]_&]:h-8 [[data-size=sm]_&]:px-2 [[data-size=sm]_&]:text-xs",
95
+ "[[data-size=md]_&]:h-10 [[data-size=md]_&]:px-3 [[data-size=md]_&]:text-sm",
96
+ "[[data-size=lg]_&]:h-12 [[data-size=lg]_&]:px-4 [[data-size=lg]_&]:text-base",
97
+ // Bordered variant
98
+ "[[data-bordered]_&]:border [[data-bordered]_&]:border-border",
99
+ className
100
+ ),
101
+ ...props
102
+ }
103
+ );
104
+ }
105
+ function TableCell({ className, ...props }) {
106
+ return /* @__PURE__ */ jsx(
107
+ "td",
108
+ {
109
+ "data-slot": "table-cell",
110
+ className: cn(
111
+ "align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0 [&>[role=checkbox]]:translate-y-[2px]",
112
+ // Size variants (inherited from parent table)
113
+ "[[data-size=sm]_&]:px-2 [[data-size=sm]_&]:py-1.5 [[data-size=sm]_&]:text-xs",
114
+ "[[data-size=md]_&]:px-3 [[data-size=md]_&]:py-2 [[data-size=md]_&]:text-sm",
115
+ "[[data-size=lg]_&]:px-4 [[data-size=lg]_&]:py-3 [[data-size=lg]_&]:text-base",
116
+ // Bordered variant
117
+ "[[data-bordered]_&]:border [[data-bordered]_&]:border-border",
118
+ className
119
+ ),
120
+ ...props
121
+ }
122
+ );
123
+ }
124
+ function TableCaption({ className, ...props }) {
125
+ return /* @__PURE__ */ jsx("caption", { "data-slot": "table-caption", className: cn("text-foreground-muted mt-4 text-sm", className), ...props });
126
+ }
127
+ function TableSortHeader({ className, children, sorted, ...props }) {
128
+ return /* @__PURE__ */ jsxs(
129
+ "button",
130
+ {
131
+ "data-slot": "table-sort-header",
132
+ className: cn(
133
+ "inline-flex items-center gap-1.5 cursor-pointer select-none hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 rounded-sm",
134
+ sorted && "text-foreground",
135
+ className
136
+ ),
137
+ ...props,
138
+ children: [
139
+ children,
140
+ /* @__PURE__ */ jsxs("span", { className: "inline-flex flex-col -space-y-0.5", children: [
141
+ /* @__PURE__ */ jsx(
142
+ "svg",
143
+ {
144
+ width: "8",
145
+ height: "5",
146
+ viewBox: "0 0 8 5",
147
+ className: cn("transition-colors", sorted === "asc" ? "text-foreground" : "text-foreground-muted"),
148
+ children: /* @__PURE__ */ jsx("path", { d: "M4 0L8 5H0L4 0Z", fill: "currentColor" })
149
+ }
150
+ ),
151
+ /* @__PURE__ */ jsx(
152
+ "svg",
153
+ {
154
+ width: "8",
155
+ height: "5",
156
+ viewBox: "0 0 8 5",
157
+ className: cn("transition-colors", sorted === "desc" ? "text-foreground" : "text-foreground-muted"),
158
+ children: /* @__PURE__ */ jsx("path", { d: "M4 5L0 0H8L4 5Z", fill: "currentColor" })
159
+ }
160
+ )
161
+ ] })
162
+ ]
163
+ }
164
+ );
165
+ }
166
+ Table.displayName = "Table";
167
+ TableHeader.displayName = "TableHeader";
168
+ TableBody.displayName = "TableBody";
169
+ TableFooter.displayName = "TableFooter";
170
+ TableHead.displayName = "TableHead";
171
+ TableRow.displayName = "TableRow";
172
+ TableCell.displayName = "TableCell";
173
+ TableCaption.displayName = "TableCaption";
174
+ TableSortHeader.displayName = "TableSortHeader";
175
+
176
+ export { Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, TableSortHeader };
177
+ //# sourceMappingURL=table.js.map
178
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/table.tsx"],"names":[],"mappings":";;;;AAIO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACeA,SAAS,KAAA,CAAM;AAAA,EACb,SAAA;AAAA,EACA,IAAA,GAAO,IAAA;AAAA,EACP,OAAA,GAAU,KAAA;AAAA,EACV,QAAA,GAAW,KAAA;AAAA,EACX,YAAA,GAAe,KAAA;AAAA,EACf,GAAG;AACL,CAAA,EAAe;AACb,EAAA,uBACE,GAAA,CAAC,KAAA,EAAA,EAAI,WAAA,EAAU,iBAAA,EAAkB,WAAU,iCAAA,EACzC,QAAA,kBAAA,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,OAAA;AAAA,MACV,WAAA,EAAW,IAAA;AAAA,MACX,gBAAc,OAAA,IAAW,MAAA;AAAA,MACzB,iBAAe,QAAA,IAAY,MAAA;AAAA,MAC3B,sBAAoB,YAAA,IAAgB,MAAA;AAAA,MACpC,SAAA,EAAW,EAAA,CAAG,uBAAA,EAAyB,SAAS,CAAA;AAAA,MAC/C,GAAG;AAAA;AAAA,GACN,EACF,CAAA;AAEJ;AAMA,SAAS,WAAA,CAAY,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AAC3E,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA;AAAA;AAAA;AAAA,QAIT,mDAAA;AAAA,QACA,sIAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,SAAA,CAAU,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AACzE,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,YAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,4BAAA;AAAA,QACA,gHAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,WAAA,CAAY,EAAE,SAAA,EAAW,GAAG,OAAM,EAAkC;AAC3E,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,yDAAA,EAA2D,SAAS,CAAA;AAAA,MACjF,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,QAAA,CAAS,EAAE,SAAA,EAAW,GAAG,OAAM,EAA+B;AACrE,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,WAAA;AAAA,MAGV,SAAA,EAAW,EAAA;AAAA,QACT,iGAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAWA,SAAS,UAAU,EAAE,SAAA,EAAW,aAAA,EAAe,GAAG,OAAM,EAAmB;AACzE,EAAA,MAAM,QAAA,GACJ,kBAAkB,KAAA,GACd,WAAA,GACA,kBAAkB,MAAA,GAChB,YAAA,GACA,aAAA,KAAkB,MAAA,GAChB,MAAA,GACA,MAAA;AAEV,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,YAAA;AAAA,MACV,WAAA,EAAW,QAAA;AAAA,MACX,SAAA,EAAW,EAAA;AAAA,QACT,qJAAA;AAAA;AAAA,QAEA,2EAAA;AAAA,QACA,4EAAA;AAAA,QACA,8EAAA;AAAA;AAAA,QAEA,8DAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,SAAA,CAAU,EAAE,SAAA,EAAW,GAAG,OAAM,EAA+B;AACtE,EAAA,uBACE,GAAA;AAAA,IAAC,IAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,YAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,oGAAA;AAAA;AAAA,QAEA,8EAAA;AAAA,QACA,4EAAA;AAAA,QACA,8EAAA;AAAA;AAAA,QAEA,8DAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAMA,SAAS,YAAA,CAAa,EAAE,SAAA,EAAW,GAAG,OAAM,EAAoC;AAC9E,EAAA,uBACE,GAAA,CAAC,SAAA,EAAA,EAAQ,WAAA,EAAU,eAAA,EAAgB,SAAA,EAAW,GAAG,oCAAA,EAAsC,SAAS,CAAA,EAAI,GAAG,KAAA,EAAO,CAAA;AAElH;AAWA,SAAS,gBAAgB,EAAE,SAAA,EAAW,UAAU,MAAA,EAAQ,GAAG,OAAM,EAAyB;AACxF,EAAA,uBACE,IAAA;AAAA,IAAC,QAAA;AAAA,IAAA;AAAA,MACC,WAAA,EAAU,mBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,oNAAA;AAAA,QACA,MAAA,IAAU,iBAAA;AAAA,QACV;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,wBACD,IAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,mCAAA,EACd,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAM,GAAA;AAAA,cACN,MAAA,EAAO,GAAA;AAAA,cACP,OAAA,EAAQ,SAAA;AAAA,cACR,WAAW,EAAA,CAAG,mBAAA,EAAqB,MAAA,KAAW,KAAA,GAAQ,oBAAoB,uBAAuB,CAAA;AAAA,cAEjG,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,iBAAA,EAAkB,MAAK,cAAA,EAAe;AAAA;AAAA,WAChD;AAAA,0BACA,GAAA;AAAA,YAAC,KAAA;AAAA,YAAA;AAAA,cACC,KAAA,EAAM,GAAA;AAAA,cACN,MAAA,EAAO,GAAA;AAAA,cACP,OAAA,EAAQ,SAAA;AAAA,cACR,WAAW,EAAA,CAAG,mBAAA,EAAqB,MAAA,KAAW,MAAA,GAAS,oBAAoB,uBAAuB,CAAA;AAAA,cAElG,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,iBAAA,EAAkB,MAAK,cAAA,EAAe;AAAA;AAAA;AAChD,SAAA,EACF;AAAA;AAAA;AAAA,GACF;AAEJ;AAEA,KAAA,CAAM,WAAA,GAAc,OAAA;AACpB,WAAA,CAAY,WAAA,GAAc,aAAA;AAC1B,SAAA,CAAU,WAAA,GAAc,WAAA;AACxB,WAAA,CAAY,WAAA,GAAc,aAAA;AAC1B,SAAA,CAAU,WAAA,GAAc,WAAA;AACxB,QAAA,CAAS,WAAA,GAAc,UAAA;AACvB,SAAA,CAAU,WAAA,GAAc,WAAA;AACxB,YAAA,CAAa,WAAA,GAAc,cAAA;AAC3B,eAAA,CAAgB,WAAA,GAAc,iBAAA","file":"table.js","sourcesContent":["import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\nimport { formatJalaliDate } from '@/lib/jalali-utils'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport type SupportedLocale = 'fa' | 'ar' | 'en'\n\n/**\n * Convert digits in a string to Persian/Arabic numerals based on locale.\n * @example convertToLocalNumbers('123', 'fa') => '۱۲۳'\n * @example convertToLocalNumbers('123', 'en') => '123'\n */\nexport function convertToLocalNumbers(text: string | number, locale: SupportedLocale): string {\n if (locale === 'fa' || locale === 'ar') {\n const persianDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']\n return String(text).replace(/\\d/g, (digit) => persianDigits[parseInt(digit)])\n }\n return String(text)\n}\n\n/**\n * Format large numbers with locale-aware suffixes (K/M/B).\n * @example formatLargeNumber(1500, 'fa') => '۱.۵ هزار'\n * @example formatLargeNumber(1500, 'en') => '1.5K'\n */\nexport function formatLargeNumber(num: number, locale: SupportedLocale): string {\n if (num >= 1_000_000_000) {\n const formatted = (num / 1_000_000_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'B' : ' میلیارد')\n }\n if (num >= 1_000_000) {\n const formatted = (num / 1_000_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'M' : ' میلیون')\n }\n if (num >= 1_000) {\n const formatted = (num / 1_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'K' : ' هزار')\n }\n return convertToLocalNumbers(num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ','), locale)\n}\n\n/**\n * Format number to Instagram-style short format (English only).\n * @example formatNumber(123456, 'short') => '123K'\n * @example formatNumber(123456, 'exact') => '123,456'\n */\nexport function formatNumber(num: number | undefined, format: 'exact' | 'short' = 'exact'): string {\n if (num === undefined || num === null) return '0'\n\n if (format === 'exact') {\n return num.toLocaleString('en-US')\n }\n\n // Short format (Instagram style)\n if (num >= 1_000_000_000) {\n return `${(num / 1_000_000_000).toFixed(1).replace(/\\.0$/, '')}B`\n }\n if (num >= 1_000_000) {\n return `${(num / 1_000_000).toFixed(1).replace(/\\.0$/, '')}M`\n }\n if (num >= 1_000) {\n return `${(num / 1_000).toFixed(1).replace(/\\.0$/, '')}K`\n }\n return num.toString()\n}\n\n/**\n * Format date to relative time with absolute on hover (Persian)\n * @example formatRelativeTime(new Date()) => '۲ ساعت پیش'\n */\nexport function formatRelativeTime(date: Date | string | number): string {\n const now = new Date()\n const then = new Date(date)\n const diffInSeconds = Math.floor((now.getTime() - then.getTime()) / 1000)\n\n if (diffInSeconds < 60) {\n return 'همین الان'\n }\n\n const diffInMinutes = Math.floor(diffInSeconds / 60)\n if (diffInMinutes < 60) {\n return `${convertToLocalNumbers(diffInMinutes, 'fa')} دقیقه پیش`\n }\n\n const diffInHours = Math.floor(diffInMinutes / 60)\n if (diffInHours < 24) {\n return `${convertToLocalNumbers(diffInHours, 'fa')} ساعت پیش`\n }\n\n const diffInDays = Math.floor(diffInHours / 24)\n if (diffInDays < 7) {\n return `${convertToLocalNumbers(diffInDays, 'fa')} روز پیش`\n }\n\n const diffInWeeks = Math.floor(diffInDays / 7)\n if (diffInWeeks < 4) {\n return `${convertToLocalNumbers(diffInWeeks, 'fa')} هفته پیش`\n }\n\n const diffInMonths = Math.floor(diffInDays / 30)\n if (diffInMonths < 12) {\n return `${convertToLocalNumbers(diffInMonths, 'fa')} ماه پیش`\n }\n\n const diffInYears = Math.floor(diffInDays / 365)\n return `${convertToLocalNumbers(diffInYears, 'fa')} سال پیش`\n}\n\n/**\n * Format date to absolute format (Persian / Jalali)\n * Uses date-fns-jalali for accurate Jalali conversion.\n * @example formatAbsoluteTime(new Date()) => '۱۵ دی ۱۴۰۳، ۱۵:۳۰'\n */\nexport function formatAbsoluteTime(date: Date | string | number): string {\n const d = new Date(date)\n return formatJalaliDate(d, 'd MMMM yyyy، HH:mm')\n}\n","'use client'\n\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/* -------------------------------------------------------------------------- */\n/* Table */\n/* -------------------------------------------------------------------------- */\n\ninterface TableProps extends React.ComponentProps<'table'> {\n /** Size variant affecting cell padding and font size */\n size?: 'sm' | 'md' | 'lg'\n /** Zebra-striped rows */\n striped?: boolean\n /** Bordered cells */\n bordered?: boolean\n /** Sticky header that stays visible when scrolling */\n stickyHeader?: boolean\n}\n\nfunction Table({\n className,\n size = 'md',\n striped = false,\n bordered = false,\n stickyHeader = false,\n ...props\n}: TableProps) {\n return (\n <div data-slot=\"table-container\" className=\"relative w-full overflow-x-auto\">\n <table\n data-slot=\"table\"\n data-size={size}\n data-striped={striped || undefined}\n data-bordered={bordered || undefined}\n data-sticky-header={stickyHeader || undefined}\n className={cn('w-full caption-bottom', className)}\n {...props}\n />\n </div>\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableHeader */\n/* -------------------------------------------------------------------------- */\n\nfunction TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {\n return (\n <thead\n data-slot=\"table-header\"\n className={cn(\n // 1.1.16 — internal row dividers use --border-muted (subtle), same\n // rationale as Card. The page-level rule of thumb: borders that\n // separate sections of one surface should whisper, not shout.\n '[&_tr]:border-b [&_tr]:border-muted bg-surface-75',\n '[[data-sticky-header]_&]:sticky [[data-sticky-header]_&]:top-0 [[data-sticky-header]_&]:z-[9] [[data-sticky-header]_&]:bg-surface-75',\n className\n )}\n {...props}\n />\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableBody */\n/* -------------------------------------------------------------------------- */\n\nfunction TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {\n return (\n <tbody\n data-slot=\"table-body\"\n className={cn(\n '[&_tr:last-child]:border-0',\n '[[data-striped]_&_tr:nth-child(even)]:bg-surface-75 [[data-striped]_&_tr:nth-child(even):hover]:bg-surface-200',\n className\n )}\n {...props}\n />\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableFooter */\n/* -------------------------------------------------------------------------- */\n\nfunction TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {\n return (\n <tfoot\n data-slot=\"table-footer\"\n className={cn('bg-muted/50 border-t font-medium [&>tr]:last:border-b-0', className)}\n {...props}\n />\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableRow */\n/* -------------------------------------------------------------------------- */\n\nfunction TableRow({ className, ...props }: React.ComponentProps<'tr'>) {\n return (\n <tr\n data-slot=\"table-row\"\n // 1.1.16 — see TableHeader: row dividers use --border-muted so the\n // table reads as a continuous list, not a fence of bright lines.\n className={cn(\n 'hover:bg-surface-200 data-[state=selected]:bg-selection border-b border-muted transition-colors',\n className\n )}\n {...props}\n />\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableHead */\n/* -------------------------------------------------------------------------- */\n\ninterface TableHeadProps extends React.ComponentProps<'th'> {\n /** Sort direction — sets aria-sort on the <th> element */\n sortDirection?: 'asc' | 'desc' | 'none'\n}\n\nfunction TableHead({ className, sortDirection, ...props }: TableHeadProps) {\n const ariaSort =\n sortDirection === 'asc'\n ? 'ascending'\n : sortDirection === 'desc'\n ? 'descending'\n : sortDirection === 'none'\n ? 'none'\n : undefined\n\n return (\n <th\n data-slot=\"table-head\"\n aria-sort={ariaSort}\n className={cn(\n 'text-foreground-lighter text-start align-middle font-semibold whitespace-nowrap [&:has([role=checkbox])]:pe-0 [&>[role=checkbox]]:translate-y-[2px]',\n // Size variants (inherited from parent table)\n '[[data-size=sm]_&]:h-8 [[data-size=sm]_&]:px-2 [[data-size=sm]_&]:text-xs',\n '[[data-size=md]_&]:h-10 [[data-size=md]_&]:px-3 [[data-size=md]_&]:text-sm',\n '[[data-size=lg]_&]:h-12 [[data-size=lg]_&]:px-4 [[data-size=lg]_&]:text-base',\n // Bordered variant\n '[[data-bordered]_&]:border [[data-bordered]_&]:border-border',\n className\n )}\n {...props}\n />\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableCell */\n/* -------------------------------------------------------------------------- */\n\nfunction TableCell({ className, ...props }: React.ComponentProps<'td'>) {\n return (\n <td\n data-slot=\"table-cell\"\n className={cn(\n 'align-middle whitespace-nowrap [&:has([role=checkbox])]:pe-0 [&>[role=checkbox]]:translate-y-[2px]',\n // Size variants (inherited from parent table)\n '[[data-size=sm]_&]:px-2 [[data-size=sm]_&]:py-1.5 [[data-size=sm]_&]:text-xs',\n '[[data-size=md]_&]:px-3 [[data-size=md]_&]:py-2 [[data-size=md]_&]:text-sm',\n '[[data-size=lg]_&]:px-4 [[data-size=lg]_&]:py-3 [[data-size=lg]_&]:text-base',\n // Bordered variant\n '[[data-bordered]_&]:border [[data-bordered]_&]:border-border',\n className\n )}\n {...props}\n />\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableCaption */\n/* -------------------------------------------------------------------------- */\n\nfunction TableCaption({ className, ...props }: React.ComponentProps<'caption'>) {\n return (\n <caption data-slot=\"table-caption\" className={cn('text-foreground-muted mt-4 text-sm', className)} {...props} />\n )\n}\n\n/* -------------------------------------------------------------------------- */\n/* TableSortHeader — clickable sort indicator for table headers */\n/* -------------------------------------------------------------------------- */\n\ninterface TableSortHeaderProps extends React.ComponentProps<'button'> {\n /** Current sort direction */\n sorted?: 'asc' | 'desc' | false\n}\n\nfunction TableSortHeader({ className, children, sorted, ...props }: TableSortHeaderProps) {\n return (\n <button\n data-slot=\"table-sort-header\"\n className={cn(\n 'inline-flex items-center gap-1.5 cursor-pointer select-none hover:text-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 rounded-sm',\n sorted && 'text-foreground',\n className\n )}\n {...props}\n >\n {children}\n <span className=\"inline-flex flex-col -space-y-0.5\">\n <svg\n width=\"8\"\n height=\"5\"\n viewBox=\"0 0 8 5\"\n className={cn('transition-colors', sorted === 'asc' ? 'text-foreground' : 'text-foreground-muted')}\n >\n <path d=\"M4 0L8 5H0L4 0Z\" fill=\"currentColor\" />\n </svg>\n <svg\n width=\"8\"\n height=\"5\"\n viewBox=\"0 0 8 5\"\n className={cn('transition-colors', sorted === 'desc' ? 'text-foreground' : 'text-foreground-muted')}\n >\n <path d=\"M4 5L0 0H8L4 5Z\" fill=\"currentColor\" />\n </svg>\n </span>\n </button>\n )\n}\n\nTable.displayName = 'Table'\nTableHeader.displayName = 'TableHeader'\nTableBody.displayName = 'TableBody'\nTableFooter.displayName = 'TableFooter'\nTableHead.displayName = 'TableHead'\nTableRow.displayName = 'TableRow'\nTableCell.displayName = 'TableCell'\nTableCaption.displayName = 'TableCaption'\nTableSortHeader.displayName = 'TableSortHeader'\n\nexport { Table, TableHeader, TableBody, TableFooter, TableHead, TableRow, TableCell, TableCaption, TableSortHeader }\n"]}
@@ -0,0 +1,140 @@
1
+ 'use client';
2
+ 'use strict';
3
+
4
+ var React = require('react');
5
+ var TabsPrimitive = require('@radix-ui/react-tabs');
6
+ var clsx = require('clsx');
7
+ var tailwindMerge = require('tailwind-merge');
8
+ var jsxRuntime = require('react/jsx-runtime');
9
+
10
+ function _interopNamespace(e) {
11
+ if (e && e.__esModule) return e;
12
+ var n = Object.create(null);
13
+ if (e) {
14
+ Object.keys(e).forEach(function (k) {
15
+ if (k !== 'default') {
16
+ var d = Object.getOwnPropertyDescriptor(e, k);
17
+ Object.defineProperty(n, k, d.get ? d : {
18
+ enumerable: true,
19
+ get: function () { return e[k]; }
20
+ });
21
+ }
22
+ });
23
+ }
24
+ n.default = e;
25
+ return Object.freeze(n);
26
+ }
27
+
28
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
29
+ var TabsPrimitive__namespace = /*#__PURE__*/_interopNamespace(TabsPrimitive);
30
+
31
+ function useDocumentDirection() {
32
+ const [direction, setDirection] = React.useState("rtl");
33
+ React.useEffect(() => {
34
+ const getDirection = () => {
35
+ if (typeof document === "undefined") return "rtl";
36
+ const htmlDir = document.documentElement.getAttribute("dir");
37
+ if (htmlDir === "ltr" || htmlDir === "rtl") {
38
+ return htmlDir;
39
+ }
40
+ const computedDir = window.getComputedStyle(document.documentElement).direction;
41
+ return computedDir === "rtl" ? "rtl" : "ltr";
42
+ };
43
+ setDirection(getDirection());
44
+ const observer = new MutationObserver(() => {
45
+ setDirection(getDirection());
46
+ });
47
+ observer.observe(document.documentElement, {
48
+ attributes: true,
49
+ attributeFilter: ["dir"]
50
+ });
51
+ return () => observer.disconnect();
52
+ }, []);
53
+ return direction;
54
+ }
55
+ function cn(...inputs) {
56
+ return tailwindMerge.twMerge(clsx.clsx(inputs));
57
+ }
58
+ var Tabs = React__namespace.forwardRef(({ dir, ...props }, ref) => {
59
+ const documentDir = useDocumentDirection();
60
+ const resolvedDir = dir ?? documentDir;
61
+ return /* @__PURE__ */ jsxRuntime.jsx(TabsPrimitive__namespace.Root, { ref, dir: resolvedDir, ...props });
62
+ });
63
+ Tabs.displayName = "Tabs";
64
+ var TabsList = React__namespace.forwardRef(
65
+ ({ className, variant = "default", size = "md", ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
66
+ TabsPrimitive__namespace.List,
67
+ {
68
+ ref,
69
+ "data-slot": "tabs-list",
70
+ "data-variant": variant,
71
+ "data-size": size,
72
+ className: cn(
73
+ "inline-flex items-center text-foreground-lighter",
74
+ // Default (pill) variant
75
+ variant === "default" && "rounded-lg bg-surface-200 p-1 gap-1",
76
+ // Underline variant
77
+ variant === "underline" && "border-b border-border gap-0",
78
+ // Outline variant
79
+ variant === "outline" && "rounded-lg border border-border gap-0",
80
+ // Sizes — height
81
+ size === "sm" && "h-8",
82
+ size === "md" && "h-9",
83
+ size === "lg" && "h-10",
84
+ className
85
+ ),
86
+ ...props
87
+ }
88
+ )
89
+ );
90
+ TabsList.displayName = TabsPrimitive__namespace.List.displayName;
91
+ var TabsTrigger = React__namespace.forwardRef(
92
+ ({ className, children, icon, badge, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsxs(
93
+ TabsPrimitive__namespace.Trigger,
94
+ {
95
+ ref,
96
+ "data-slot": "tabs-trigger",
97
+ className: cn(
98
+ "inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
99
+ // Default (pill) variant
100
+ "[[data-variant=default]_&]:rounded-md [[data-variant=default]_&]:px-3 [[data-variant=default]_&]:data-[state=active]:bg-background [[data-variant=default]_&]:data-[state=active]:text-foreground [[data-variant=default]_&]:data-[state=active]:shadow-sm",
101
+ // Underline variant
102
+ "[[data-variant=underline]_&]:px-4 [[data-variant=underline]_&]:border-b-2 [[data-variant=underline]_&]:border-transparent [[data-variant=underline]_&]:rounded-none [[data-variant=underline]_&]:data-[state=active]:border-brand [[data-variant=underline]_&]:data-[state=active]:text-foreground",
103
+ // Outline variant
104
+ "[[data-variant=outline]_&]:px-4 [[data-variant=outline]_&]:border-e [[data-variant=outline]_&]:border-border [[data-variant=outline]_&]:last:border-e-0 [[data-variant=outline]_&]:first:rounded-s-lg [[data-variant=outline]_&]:last:rounded-e-lg [[data-variant=outline]_&]:data-[state=active]:bg-surface-200 [[data-variant=outline]_&]:data-[state=active]:text-foreground",
105
+ // Sizes
106
+ "[[data-size=sm]_&]:text-xs [[data-size=sm]_&]:h-full",
107
+ "[[data-size=md]_&]:text-sm [[data-size=md]_&]:h-full",
108
+ "[[data-size=lg]_&]:text-base [[data-size=lg]_&]:h-full",
109
+ className
110
+ ),
111
+ ...props,
112
+ children: [
113
+ icon && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "flex-shrink-0", children: icon }),
114
+ children,
115
+ badge && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded-full bg-surface-300 text-2xs font-semibold", children: badge })
116
+ ]
117
+ }
118
+ )
119
+ );
120
+ TabsTrigger.displayName = TabsPrimitive__namespace.Trigger.displayName;
121
+ var TabsContent = React__namespace.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(
122
+ TabsPrimitive__namespace.Content,
123
+ {
124
+ ref,
125
+ "data-slot": "tabs-content",
126
+ className: cn(
127
+ "mt-2 p-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
128
+ className
129
+ ),
130
+ ...props
131
+ }
132
+ ));
133
+ TabsContent.displayName = TabsPrimitive__namespace.Content.displayName;
134
+
135
+ exports.Tabs = Tabs;
136
+ exports.TabsContent = TabsContent;
137
+ exports.TabsList = TabsList;
138
+ exports.TabsTrigger = TabsTrigger;
139
+ //# sourceMappingURL=tabs.cjs.map
140
+ //# sourceMappingURL=tabs.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/use-document-direction.ts","../../../src/lib/utils.ts","../../../src/components/ui/tabs.tsx"],"names":["useState","useEffect","twMerge","clsx","React","TabsPrimitive","jsx","jsxs"],"mappings":"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","file":"tabs.cjs","sourcesContent":["'use client'\n\nimport { useState, useEffect } from 'react'\n\ntype Direction = 'ltr' | 'rtl'\n\nfunction useDocumentDirection(): Direction {\n const [direction, setDirection] = useState<Direction>('rtl')\n\n useEffect(() => {\n const getDirection = (): Direction => {\n if (typeof document === 'undefined') return 'rtl'\n const htmlDir = document.documentElement.getAttribute('dir')\n if (htmlDir === 'ltr' || htmlDir === 'rtl') {\n return htmlDir\n }\n const computedDir = window.getComputedStyle(document.documentElement).direction\n return computedDir === 'rtl' ? 'rtl' : 'ltr'\n }\n\n setDirection(getDirection())\n\n const observer = new MutationObserver(() => {\n setDirection(getDirection())\n })\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['dir'],\n })\n\n return () => observer.disconnect()\n }, [])\n\n return direction\n}\n\nexport { useDocumentDirection }\nexport type { Direction }\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\nimport { formatJalaliDate } from '@/lib/jalali-utils'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport type SupportedLocale = 'fa' | 'ar' | 'en'\n\n/**\n * Convert digits in a string to Persian/Arabic numerals based on locale.\n * @example convertToLocalNumbers('123', 'fa') => '۱۲۳'\n * @example convertToLocalNumbers('123', 'en') => '123'\n */\nexport function convertToLocalNumbers(text: string | number, locale: SupportedLocale): string {\n if (locale === 'fa' || locale === 'ar') {\n const persianDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']\n return String(text).replace(/\\d/g, (digit) => persianDigits[parseInt(digit)])\n }\n return String(text)\n}\n\n/**\n * Format large numbers with locale-aware suffixes (K/M/B).\n * @example formatLargeNumber(1500, 'fa') => '۱.۵ هزار'\n * @example formatLargeNumber(1500, 'en') => '1.5K'\n */\nexport function formatLargeNumber(num: number, locale: SupportedLocale): string {\n if (num >= 1_000_000_000) {\n const formatted = (num / 1_000_000_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'B' : ' میلیارد')\n }\n if (num >= 1_000_000) {\n const formatted = (num / 1_000_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'M' : ' میلیون')\n }\n if (num >= 1_000) {\n const formatted = (num / 1_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'K' : ' هزار')\n }\n return convertToLocalNumbers(num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ','), locale)\n}\n\n/**\n * Format number to Instagram-style short format (English only).\n * @example formatNumber(123456, 'short') => '123K'\n * @example formatNumber(123456, 'exact') => '123,456'\n */\nexport function formatNumber(num: number | undefined, format: 'exact' | 'short' = 'exact'): string {\n if (num === undefined || num === null) return '0'\n\n if (format === 'exact') {\n return num.toLocaleString('en-US')\n }\n\n // Short format (Instagram style)\n if (num >= 1_000_000_000) {\n return `${(num / 1_000_000_000).toFixed(1).replace(/\\.0$/, '')}B`\n }\n if (num >= 1_000_000) {\n return `${(num / 1_000_000).toFixed(1).replace(/\\.0$/, '')}M`\n }\n if (num >= 1_000) {\n return `${(num / 1_000).toFixed(1).replace(/\\.0$/, '')}K`\n }\n return num.toString()\n}\n\n/**\n * Format date to relative time with absolute on hover (Persian)\n * @example formatRelativeTime(new Date()) => '۲ ساعت پیش'\n */\nexport function formatRelativeTime(date: Date | string | number): string {\n const now = new Date()\n const then = new Date(date)\n const diffInSeconds = Math.floor((now.getTime() - then.getTime()) / 1000)\n\n if (diffInSeconds < 60) {\n return 'همین الان'\n }\n\n const diffInMinutes = Math.floor(diffInSeconds / 60)\n if (diffInMinutes < 60) {\n return `${convertToLocalNumbers(diffInMinutes, 'fa')} دقیقه پیش`\n }\n\n const diffInHours = Math.floor(diffInMinutes / 60)\n if (diffInHours < 24) {\n return `${convertToLocalNumbers(diffInHours, 'fa')} ساعت پیش`\n }\n\n const diffInDays = Math.floor(diffInHours / 24)\n if (diffInDays < 7) {\n return `${convertToLocalNumbers(diffInDays, 'fa')} روز پیش`\n }\n\n const diffInWeeks = Math.floor(diffInDays / 7)\n if (diffInWeeks < 4) {\n return `${convertToLocalNumbers(diffInWeeks, 'fa')} هفته پیش`\n }\n\n const diffInMonths = Math.floor(diffInDays / 30)\n if (diffInMonths < 12) {\n return `${convertToLocalNumbers(diffInMonths, 'fa')} ماه پیش`\n }\n\n const diffInYears = Math.floor(diffInDays / 365)\n return `${convertToLocalNumbers(diffInYears, 'fa')} سال پیش`\n}\n\n/**\n * Format date to absolute format (Persian / Jalali)\n * Uses date-fns-jalali for accurate Jalali conversion.\n * @example formatAbsoluteTime(new Date()) => '۱۵ دی ۱۴۰۳، ۱۵:۳۰'\n */\nexport function formatAbsoluteTime(date: Date | string | number): string {\n const d = new Date(date)\n return formatJalaliDate(d, 'd MMMM yyyy، HH:mm')\n}\n","'use client'\n\nimport * as React from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\n\nimport { useDocumentDirection, type Direction } from '@/hooks/use-document-direction'\nimport { cn } from '@/lib/utils'\n\n/* -------------------------------------------------------------------------- */\n/* Tabs Root */\n/* -------------------------------------------------------------------------- */\n\nconst Tabs = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>\n>(({ dir, ...props }, ref) => {\n // Forward document `dir` to Radix so ArrowLeft/ArrowRight semantics flip in RTL.\n const documentDir = useDocumentDirection()\n const resolvedDir = (dir as Direction) ?? documentDir\n return <TabsPrimitive.Root ref={ref} dir={resolvedDir} {...props} />\n})\nTabs.displayName = 'Tabs'\n\n/* -------------------------------------------------------------------------- */\n/* TabsList */\n/* -------------------------------------------------------------------------- */\n\ninterface TabsListProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> {\n /** Visual variant */\n variant?: 'default' | 'underline' | 'outline'\n /** Size */\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst TabsList = React.forwardRef<React.ElementRef<typeof TabsPrimitive.List>, TabsListProps>(\n ({ className, variant = 'default', size = 'md', ...props }, ref) => (\n <TabsPrimitive.List\n ref={ref}\n data-slot=\"tabs-list\"\n data-variant={variant}\n data-size={size}\n className={cn(\n 'inline-flex items-center text-foreground-lighter',\n // Default (pill) variant\n variant === 'default' && 'rounded-lg bg-surface-200 p-1 gap-1',\n // Underline variant\n variant === 'underline' && 'border-b border-border gap-0',\n // Outline variant\n variant === 'outline' && 'rounded-lg border border-border gap-0',\n // Sizes — height\n size === 'sm' && 'h-8',\n size === 'md' && 'h-9',\n size === 'lg' && 'h-10',\n className\n )}\n {...props}\n />\n )\n)\nTabsList.displayName = TabsPrimitive.List.displayName\n\n/* -------------------------------------------------------------------------- */\n/* TabsTrigger */\n/* -------------------------------------------------------------------------- */\n\ninterface TabsTriggerProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> {\n /** Icon rendered before the label */\n icon?: React.ReactNode\n /** Badge/count rendered after the label */\n badge?: React.ReactNode\n}\n\nconst TabsTrigger = React.forwardRef<React.ElementRef<typeof TabsPrimitive.Trigger>, TabsTriggerProps>(\n ({ className, children, icon, badge, ...props }, ref) => (\n <TabsPrimitive.Trigger\n ref={ref}\n data-slot=\"tabs-trigger\"\n className={cn(\n 'inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n // Default (pill) variant\n '[[data-variant=default]_&]:rounded-md [[data-variant=default]_&]:px-3 [[data-variant=default]_&]:data-[state=active]:bg-background [[data-variant=default]_&]:data-[state=active]:text-foreground [[data-variant=default]_&]:data-[state=active]:shadow-sm',\n // Underline variant\n '[[data-variant=underline]_&]:px-4 [[data-variant=underline]_&]:border-b-2 [[data-variant=underline]_&]:border-transparent [[data-variant=underline]_&]:rounded-none [[data-variant=underline]_&]:data-[state=active]:border-brand [[data-variant=underline]_&]:data-[state=active]:text-foreground',\n // Outline variant\n '[[data-variant=outline]_&]:px-4 [[data-variant=outline]_&]:border-e [[data-variant=outline]_&]:border-border [[data-variant=outline]_&]:last:border-e-0 [[data-variant=outline]_&]:first:rounded-s-lg [[data-variant=outline]_&]:last:rounded-e-lg [[data-variant=outline]_&]:data-[state=active]:bg-surface-200 [[data-variant=outline]_&]:data-[state=active]:text-foreground',\n // Sizes\n '[[data-size=sm]_&]:text-xs [[data-size=sm]_&]:h-full',\n '[[data-size=md]_&]:text-sm [[data-size=md]_&]:h-full',\n '[[data-size=lg]_&]:text-base [[data-size=lg]_&]:h-full',\n className\n )}\n {...props}\n >\n {icon && <span className=\"flex-shrink-0\">{icon}</span>}\n {children}\n {badge && (\n <span className=\"inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded-full bg-surface-300 text-2xs font-semibold\">\n {badge}\n </span>\n )}\n </TabsPrimitive.Trigger>\n )\n)\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName\n\n/* -------------------------------------------------------------------------- */\n/* TabsContent */\n/* -------------------------------------------------------------------------- */\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n data-slot=\"tabs-content\"\n className={cn(\n 'mt-2 p-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n className\n )}\n {...props}\n />\n))\nTabsContent.displayName = TabsPrimitive.Content.displayName\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent }\n"]}
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
3
+
4
+ declare const Tabs: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
5
+ interface TabsListProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> {
6
+ /** Visual variant */
7
+ variant?: 'default' | 'underline' | 'outline';
8
+ /** Size */
9
+ size?: 'sm' | 'md' | 'lg';
10
+ }
11
+ declare const TabsList: React.ForwardRefExoticComponent<TabsListProps & React.RefAttributes<HTMLDivElement>>;
12
+ interface TabsTriggerProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> {
13
+ /** Icon rendered before the label */
14
+ icon?: React.ReactNode;
15
+ /** Badge/count rendered after the label */
16
+ badge?: React.ReactNode;
17
+ }
18
+ declare const TabsTrigger: React.ForwardRefExoticComponent<TabsTriggerProps & React.RefAttributes<HTMLButtonElement>>;
19
+ declare const TabsContent: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
20
+
21
+ export { Tabs, TabsContent, TabsList, TabsTrigger };
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
3
+
4
+ declare const Tabs: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
5
+ interface TabsListProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> {
6
+ /** Visual variant */
7
+ variant?: 'default' | 'underline' | 'outline';
8
+ /** Size */
9
+ size?: 'sm' | 'md' | 'lg';
10
+ }
11
+ declare const TabsList: React.ForwardRefExoticComponent<TabsListProps & React.RefAttributes<HTMLDivElement>>;
12
+ interface TabsTriggerProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> {
13
+ /** Icon rendered before the label */
14
+ icon?: React.ReactNode;
15
+ /** Badge/count rendered after the label */
16
+ badge?: React.ReactNode;
17
+ }
18
+ declare const TabsTrigger: React.ForwardRefExoticComponent<TabsTriggerProps & React.RefAttributes<HTMLButtonElement>>;
19
+ declare const TabsContent: React.ForwardRefExoticComponent<Omit<TabsPrimitive.TabsContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
20
+
21
+ export { Tabs, TabsContent, TabsList, TabsTrigger };
@@ -0,0 +1,115 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+ import { useState, useEffect } from 'react';
4
+ import * as TabsPrimitive from '@radix-ui/react-tabs';
5
+ import { clsx } from 'clsx';
6
+ import { twMerge } from 'tailwind-merge';
7
+ import { jsx, jsxs } from 'react/jsx-runtime';
8
+
9
+ function useDocumentDirection() {
10
+ const [direction, setDirection] = useState("rtl");
11
+ useEffect(() => {
12
+ const getDirection = () => {
13
+ if (typeof document === "undefined") return "rtl";
14
+ const htmlDir = document.documentElement.getAttribute("dir");
15
+ if (htmlDir === "ltr" || htmlDir === "rtl") {
16
+ return htmlDir;
17
+ }
18
+ const computedDir = window.getComputedStyle(document.documentElement).direction;
19
+ return computedDir === "rtl" ? "rtl" : "ltr";
20
+ };
21
+ setDirection(getDirection());
22
+ const observer = new MutationObserver(() => {
23
+ setDirection(getDirection());
24
+ });
25
+ observer.observe(document.documentElement, {
26
+ attributes: true,
27
+ attributeFilter: ["dir"]
28
+ });
29
+ return () => observer.disconnect();
30
+ }, []);
31
+ return direction;
32
+ }
33
+ function cn(...inputs) {
34
+ return twMerge(clsx(inputs));
35
+ }
36
+ var Tabs = React.forwardRef(({ dir, ...props }, ref) => {
37
+ const documentDir = useDocumentDirection();
38
+ const resolvedDir = dir ?? documentDir;
39
+ return /* @__PURE__ */ jsx(TabsPrimitive.Root, { ref, dir: resolvedDir, ...props });
40
+ });
41
+ Tabs.displayName = "Tabs";
42
+ var TabsList = React.forwardRef(
43
+ ({ className, variant = "default", size = "md", ...props }, ref) => /* @__PURE__ */ jsx(
44
+ TabsPrimitive.List,
45
+ {
46
+ ref,
47
+ "data-slot": "tabs-list",
48
+ "data-variant": variant,
49
+ "data-size": size,
50
+ className: cn(
51
+ "inline-flex items-center text-foreground-lighter",
52
+ // Default (pill) variant
53
+ variant === "default" && "rounded-lg bg-surface-200 p-1 gap-1",
54
+ // Underline variant
55
+ variant === "underline" && "border-b border-border gap-0",
56
+ // Outline variant
57
+ variant === "outline" && "rounded-lg border border-border gap-0",
58
+ // Sizes — height
59
+ size === "sm" && "h-8",
60
+ size === "md" && "h-9",
61
+ size === "lg" && "h-10",
62
+ className
63
+ ),
64
+ ...props
65
+ }
66
+ )
67
+ );
68
+ TabsList.displayName = TabsPrimitive.List.displayName;
69
+ var TabsTrigger = React.forwardRef(
70
+ ({ className, children, icon, badge, ...props }, ref) => /* @__PURE__ */ jsxs(
71
+ TabsPrimitive.Trigger,
72
+ {
73
+ ref,
74
+ "data-slot": "tabs-trigger",
75
+ className: cn(
76
+ "inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
77
+ // Default (pill) variant
78
+ "[[data-variant=default]_&]:rounded-md [[data-variant=default]_&]:px-3 [[data-variant=default]_&]:data-[state=active]:bg-background [[data-variant=default]_&]:data-[state=active]:text-foreground [[data-variant=default]_&]:data-[state=active]:shadow-sm",
79
+ // Underline variant
80
+ "[[data-variant=underline]_&]:px-4 [[data-variant=underline]_&]:border-b-2 [[data-variant=underline]_&]:border-transparent [[data-variant=underline]_&]:rounded-none [[data-variant=underline]_&]:data-[state=active]:border-brand [[data-variant=underline]_&]:data-[state=active]:text-foreground",
81
+ // Outline variant
82
+ "[[data-variant=outline]_&]:px-4 [[data-variant=outline]_&]:border-e [[data-variant=outline]_&]:border-border [[data-variant=outline]_&]:last:border-e-0 [[data-variant=outline]_&]:first:rounded-s-lg [[data-variant=outline]_&]:last:rounded-e-lg [[data-variant=outline]_&]:data-[state=active]:bg-surface-200 [[data-variant=outline]_&]:data-[state=active]:text-foreground",
83
+ // Sizes
84
+ "[[data-size=sm]_&]:text-xs [[data-size=sm]_&]:h-full",
85
+ "[[data-size=md]_&]:text-sm [[data-size=md]_&]:h-full",
86
+ "[[data-size=lg]_&]:text-base [[data-size=lg]_&]:h-full",
87
+ className
88
+ ),
89
+ ...props,
90
+ children: [
91
+ icon && /* @__PURE__ */ jsx("span", { className: "flex-shrink-0", children: icon }),
92
+ children,
93
+ badge && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded-full bg-surface-300 text-2xs font-semibold", children: badge })
94
+ ]
95
+ }
96
+ )
97
+ );
98
+ TabsTrigger.displayName = TabsPrimitive.Trigger.displayName;
99
+ var TabsContent = React.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
100
+ TabsPrimitive.Content,
101
+ {
102
+ ref,
103
+ "data-slot": "tabs-content",
104
+ className: cn(
105
+ "mt-2 p-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
106
+ className
107
+ ),
108
+ ...props
109
+ }
110
+ ));
111
+ TabsContent.displayName = TabsPrimitive.Content.displayName;
112
+
113
+ export { Tabs, TabsContent, TabsList, TabsTrigger };
114
+ //# sourceMappingURL=tabs.js.map
115
+ //# sourceMappingURL=tabs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/hooks/use-document-direction.ts","../../../src/lib/utils.ts","../../../src/components/ui/tabs.tsx"],"names":[],"mappings":";;;;;;;AAMA,SAAS,oBAAA,GAAkC;AACzC,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAoB,KAAK,CAAA;AAE3D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,eAAe,MAAiB;AACpC,MAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,KAAA;AAC5C,MAAA,MAAM,OAAA,GAAU,QAAA,CAAS,eAAA,CAAgB,YAAA,CAAa,KAAK,CAAA;AAC3D,MAAA,IAAI,OAAA,KAAY,KAAA,IAAS,OAAA,KAAY,KAAA,EAAO;AAC1C,QAAA,OAAO,OAAA;AAAA,MACT;AACA,MAAA,MAAM,WAAA,GAAc,MAAA,CAAO,gBAAA,CAAiB,QAAA,CAAS,eAAe,CAAA,CAAE,SAAA;AACtE,MAAA,OAAO,WAAA,KAAgB,QAAQ,KAAA,GAAQ,KAAA;AAAA,IACzC,CAAA;AAEA,IAAA,YAAA,CAAa,cAAc,CAAA;AAE3B,IAAA,MAAM,QAAA,GAAW,IAAI,gBAAA,CAAiB,MAAM;AAC1C,MAAA,YAAA,CAAa,cAAc,CAAA;AAAA,IAC7B,CAAC,CAAA;AAED,IAAA,QAAA,CAAS,OAAA,CAAQ,SAAS,eAAA,EAAiB;AAAA,MACzC,UAAA,EAAY,IAAA;AAAA,MACZ,eAAA,EAAiB,CAAC,KAAK;AAAA,KACxB,CAAA;AAED,IAAA,OAAO,MAAM,SAAS,UAAA,EAAW;AAAA,EACnC,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,OAAO,SAAA;AACT;AC/BO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACMA,IAAM,IAAA,GAAa,iBAGjB,CAAC,EAAE,KAAK,GAAG,KAAA,IAAS,GAAA,KAAQ;AAE5B,EAAA,MAAM,cAAc,oBAAA,EAAqB;AACzC,EAAA,MAAM,cAAe,GAAA,IAAqB,WAAA;AAC1C,EAAA,2BAAsB,aAAA,CAAA,IAAA,EAAd,EAAmB,KAAU,GAAA,EAAK,WAAA,EAAc,GAAG,KAAA,EAAO,CAAA;AACpE,CAAC;AACD,IAAA,CAAK,WAAA,GAAc,MAAA;AAanB,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACrB,CAAC,EAAE,SAAA,EAAW,OAAA,GAAU,SAAA,EAAW,OAAO,IAAA,EAAM,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC1D,GAAA;AAAA,IAAe,aAAA,CAAA,IAAA;AAAA,IAAd;AAAA,MACC,GAAA;AAAA,MACA,WAAA,EAAU,WAAA;AAAA,MACV,cAAA,EAAc,OAAA;AAAA,MACd,WAAA,EAAW,IAAA;AAAA,MACX,SAAA,EAAW,EAAA;AAAA,QACT,kDAAA;AAAA;AAAA,QAEA,YAAY,SAAA,IAAa,qCAAA;AAAA;AAAA,QAEzB,YAAY,WAAA,IAAe,8BAAA;AAAA;AAAA,QAE3B,YAAY,SAAA,IAAa,uCAAA;AAAA;AAAA,QAEzB,SAAS,IAAA,IAAQ,KAAA;AAAA,QACjB,SAAS,IAAA,IAAQ,KAAA;AAAA,QACjB,SAAS,IAAA,IAAQ,MAAA;AAAA,QACjB;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA;AAGV;AACA,QAAA,CAAS,cAA4B,aAAA,CAAA,IAAA,CAAK,WAAA;AAa1C,IAAM,WAAA,GAAoB,KAAA,CAAA,UAAA;AAAA,EACxB,CAAC,EAAE,SAAA,EAAW,QAAA,EAAU,MAAM,KAAA,EAAO,GAAG,KAAA,EAAM,EAAG,GAAA,qBAC/C,IAAA;AAAA,IAAe,aAAA,CAAA,OAAA;AAAA,IAAd;AAAA,MACC,GAAA;AAAA,MACA,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,0QAAA;AAAA;AAAA,QAEA,4PAAA;AAAA;AAAA,QAEA,oSAAA;AAAA;AAAA,QAEA,iXAAA;AAAA;AAAA,QAEA,sDAAA;AAAA,QACA,sDAAA;AAAA,QACA,wDAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,IAAA,oBAAQ,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,eAAA,EAAiB,QAAA,EAAA,IAAA,EAAK,CAAA;AAAA,QAC9C,QAAA;AAAA,QACA,KAAA,oBACC,GAAA,CAAC,MAAA,EAAA,EAAK,SAAA,EAAU,uHACb,QAAA,EAAA,KAAA,EACH;AAAA;AAAA;AAAA;AAIR;AACA,WAAA,CAAY,cAA4B,aAAA,CAAA,OAAA,CAAQ,WAAA;AAMhD,IAAM,WAAA,GAAoB,iBAGxB,CAAC,EAAE,WAAW,GAAG,KAAA,IAAS,GAAA,qBAC1B,GAAA;AAAA,EAAe,aAAA,CAAA,OAAA;AAAA,EAAd;AAAA,IACC,GAAA;AAAA,IACA,WAAA,EAAU,cAAA;AAAA,IACV,SAAA,EAAW,EAAA;AAAA,MACT,qIAAA;AAAA,MACA;AAAA,KACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,WAAA,CAAY,cAA4B,aAAA,CAAA,OAAA,CAAQ,WAAA","file":"tabs.js","sourcesContent":["'use client'\n\nimport { useState, useEffect } from 'react'\n\ntype Direction = 'ltr' | 'rtl'\n\nfunction useDocumentDirection(): Direction {\n const [direction, setDirection] = useState<Direction>('rtl')\n\n useEffect(() => {\n const getDirection = (): Direction => {\n if (typeof document === 'undefined') return 'rtl'\n const htmlDir = document.documentElement.getAttribute('dir')\n if (htmlDir === 'ltr' || htmlDir === 'rtl') {\n return htmlDir\n }\n const computedDir = window.getComputedStyle(document.documentElement).direction\n return computedDir === 'rtl' ? 'rtl' : 'ltr'\n }\n\n setDirection(getDirection())\n\n const observer = new MutationObserver(() => {\n setDirection(getDirection())\n })\n\n observer.observe(document.documentElement, {\n attributes: true,\n attributeFilter: ['dir'],\n })\n\n return () => observer.disconnect()\n }, [])\n\n return direction\n}\n\nexport { useDocumentDirection }\nexport type { Direction }\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\nimport { formatJalaliDate } from '@/lib/jalali-utils'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n\nexport type SupportedLocale = 'fa' | 'ar' | 'en'\n\n/**\n * Convert digits in a string to Persian/Arabic numerals based on locale.\n * @example convertToLocalNumbers('123', 'fa') => '۱۲۳'\n * @example convertToLocalNumbers('123', 'en') => '123'\n */\nexport function convertToLocalNumbers(text: string | number, locale: SupportedLocale): string {\n if (locale === 'fa' || locale === 'ar') {\n const persianDigits = ['۰', '۱', '۲', '۳', '۴', '۵', '۶', '۷', '۸', '۹']\n return String(text).replace(/\\d/g, (digit) => persianDigits[parseInt(digit)])\n }\n return String(text)\n}\n\n/**\n * Format large numbers with locale-aware suffixes (K/M/B).\n * @example formatLargeNumber(1500, 'fa') => '۱.۵ هزار'\n * @example formatLargeNumber(1500, 'en') => '1.5K'\n */\nexport function formatLargeNumber(num: number, locale: SupportedLocale): string {\n if (num >= 1_000_000_000) {\n const formatted = (num / 1_000_000_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'B' : ' میلیارد')\n }\n if (num >= 1_000_000) {\n const formatted = (num / 1_000_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'M' : ' میلیون')\n }\n if (num >= 1_000) {\n const formatted = (num / 1_000).toFixed(1).replace(/\\.0$/, '')\n return convertToLocalNumbers(formatted, locale) + (locale === 'en' ? 'K' : ' هزار')\n }\n return convertToLocalNumbers(num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ','), locale)\n}\n\n/**\n * Format number to Instagram-style short format (English only).\n * @example formatNumber(123456, 'short') => '123K'\n * @example formatNumber(123456, 'exact') => '123,456'\n */\nexport function formatNumber(num: number | undefined, format: 'exact' | 'short' = 'exact'): string {\n if (num === undefined || num === null) return '0'\n\n if (format === 'exact') {\n return num.toLocaleString('en-US')\n }\n\n // Short format (Instagram style)\n if (num >= 1_000_000_000) {\n return `${(num / 1_000_000_000).toFixed(1).replace(/\\.0$/, '')}B`\n }\n if (num >= 1_000_000) {\n return `${(num / 1_000_000).toFixed(1).replace(/\\.0$/, '')}M`\n }\n if (num >= 1_000) {\n return `${(num / 1_000).toFixed(1).replace(/\\.0$/, '')}K`\n }\n return num.toString()\n}\n\n/**\n * Format date to relative time with absolute on hover (Persian)\n * @example formatRelativeTime(new Date()) => '۲ ساعت پیش'\n */\nexport function formatRelativeTime(date: Date | string | number): string {\n const now = new Date()\n const then = new Date(date)\n const diffInSeconds = Math.floor((now.getTime() - then.getTime()) / 1000)\n\n if (diffInSeconds < 60) {\n return 'همین الان'\n }\n\n const diffInMinutes = Math.floor(diffInSeconds / 60)\n if (diffInMinutes < 60) {\n return `${convertToLocalNumbers(diffInMinutes, 'fa')} دقیقه پیش`\n }\n\n const diffInHours = Math.floor(diffInMinutes / 60)\n if (diffInHours < 24) {\n return `${convertToLocalNumbers(diffInHours, 'fa')} ساعت پیش`\n }\n\n const diffInDays = Math.floor(diffInHours / 24)\n if (diffInDays < 7) {\n return `${convertToLocalNumbers(diffInDays, 'fa')} روز پیش`\n }\n\n const diffInWeeks = Math.floor(diffInDays / 7)\n if (diffInWeeks < 4) {\n return `${convertToLocalNumbers(diffInWeeks, 'fa')} هفته پیش`\n }\n\n const diffInMonths = Math.floor(diffInDays / 30)\n if (diffInMonths < 12) {\n return `${convertToLocalNumbers(diffInMonths, 'fa')} ماه پیش`\n }\n\n const diffInYears = Math.floor(diffInDays / 365)\n return `${convertToLocalNumbers(diffInYears, 'fa')} سال پیش`\n}\n\n/**\n * Format date to absolute format (Persian / Jalali)\n * Uses date-fns-jalali for accurate Jalali conversion.\n * @example formatAbsoluteTime(new Date()) => '۱۵ دی ۱۴۰۳، ۱۵:۳۰'\n */\nexport function formatAbsoluteTime(date: Date | string | number): string {\n const d = new Date(date)\n return formatJalaliDate(d, 'd MMMM yyyy، HH:mm')\n}\n","'use client'\n\nimport * as React from 'react'\nimport * as TabsPrimitive from '@radix-ui/react-tabs'\n\nimport { useDocumentDirection, type Direction } from '@/hooks/use-document-direction'\nimport { cn } from '@/lib/utils'\n\n/* -------------------------------------------------------------------------- */\n/* Tabs Root */\n/* -------------------------------------------------------------------------- */\n\nconst Tabs = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Root>\n>(({ dir, ...props }, ref) => {\n // Forward document `dir` to Radix so ArrowLeft/ArrowRight semantics flip in RTL.\n const documentDir = useDocumentDirection()\n const resolvedDir = (dir as Direction) ?? documentDir\n return <TabsPrimitive.Root ref={ref} dir={resolvedDir} {...props} />\n})\nTabs.displayName = 'Tabs'\n\n/* -------------------------------------------------------------------------- */\n/* TabsList */\n/* -------------------------------------------------------------------------- */\n\ninterface TabsListProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.List> {\n /** Visual variant */\n variant?: 'default' | 'underline' | 'outline'\n /** Size */\n size?: 'sm' | 'md' | 'lg'\n}\n\nconst TabsList = React.forwardRef<React.ElementRef<typeof TabsPrimitive.List>, TabsListProps>(\n ({ className, variant = 'default', size = 'md', ...props }, ref) => (\n <TabsPrimitive.List\n ref={ref}\n data-slot=\"tabs-list\"\n data-variant={variant}\n data-size={size}\n className={cn(\n 'inline-flex items-center text-foreground-lighter',\n // Default (pill) variant\n variant === 'default' && 'rounded-lg bg-surface-200 p-1 gap-1',\n // Underline variant\n variant === 'underline' && 'border-b border-border gap-0',\n // Outline variant\n variant === 'outline' && 'rounded-lg border border-border gap-0',\n // Sizes — height\n size === 'sm' && 'h-8',\n size === 'md' && 'h-9',\n size === 'lg' && 'h-10',\n className\n )}\n {...props}\n />\n )\n)\nTabsList.displayName = TabsPrimitive.List.displayName\n\n/* -------------------------------------------------------------------------- */\n/* TabsTrigger */\n/* -------------------------------------------------------------------------- */\n\ninterface TabsTriggerProps extends React.ComponentPropsWithoutRef<typeof TabsPrimitive.Trigger> {\n /** Icon rendered before the label */\n icon?: React.ReactNode\n /** Badge/count rendered after the label */\n badge?: React.ReactNode\n}\n\nconst TabsTrigger = React.forwardRef<React.ElementRef<typeof TabsPrimitive.Trigger>, TabsTriggerProps>(\n ({ className, children, icon, badge, ...props }, ref) => (\n <TabsPrimitive.Trigger\n ref={ref}\n data-slot=\"tabs-trigger\"\n className={cn(\n 'inline-flex items-center justify-center gap-1.5 whitespace-nowrap font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50',\n // Default (pill) variant\n '[[data-variant=default]_&]:rounded-md [[data-variant=default]_&]:px-3 [[data-variant=default]_&]:data-[state=active]:bg-background [[data-variant=default]_&]:data-[state=active]:text-foreground [[data-variant=default]_&]:data-[state=active]:shadow-sm',\n // Underline variant\n '[[data-variant=underline]_&]:px-4 [[data-variant=underline]_&]:border-b-2 [[data-variant=underline]_&]:border-transparent [[data-variant=underline]_&]:rounded-none [[data-variant=underline]_&]:data-[state=active]:border-brand [[data-variant=underline]_&]:data-[state=active]:text-foreground',\n // Outline variant\n '[[data-variant=outline]_&]:px-4 [[data-variant=outline]_&]:border-e [[data-variant=outline]_&]:border-border [[data-variant=outline]_&]:last:border-e-0 [[data-variant=outline]_&]:first:rounded-s-lg [[data-variant=outline]_&]:last:rounded-e-lg [[data-variant=outline]_&]:data-[state=active]:bg-surface-200 [[data-variant=outline]_&]:data-[state=active]:text-foreground',\n // Sizes\n '[[data-size=sm]_&]:text-xs [[data-size=sm]_&]:h-full',\n '[[data-size=md]_&]:text-sm [[data-size=md]_&]:h-full',\n '[[data-size=lg]_&]:text-base [[data-size=lg]_&]:h-full',\n className\n )}\n {...props}\n >\n {icon && <span className=\"flex-shrink-0\">{icon}</span>}\n {children}\n {badge && (\n <span className=\"inline-flex items-center justify-center min-w-[1.25rem] h-5 px-1 rounded-full bg-surface-300 text-2xs font-semibold\">\n {badge}\n </span>\n )}\n </TabsPrimitive.Trigger>\n )\n)\nTabsTrigger.displayName = TabsPrimitive.Trigger.displayName\n\n/* -------------------------------------------------------------------------- */\n/* TabsContent */\n/* -------------------------------------------------------------------------- */\n\nconst TabsContent = React.forwardRef<\n React.ElementRef<typeof TabsPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TabsPrimitive.Content>\n>(({ className, ...props }, ref) => (\n <TabsPrimitive.Content\n ref={ref}\n data-slot=\"tabs-content\"\n className={cn(\n 'mt-2 p-4 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n className\n )}\n {...props}\n />\n))\nTabsContent.displayName = TabsPrimitive.Content.displayName\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent }\n"]}