@parto-system-design/ui 1.1.11 → 1.1.16

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 (411) 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.d.cts +1 -1
  60. package/dist/components/ui/badge.d.ts +1 -1
  61. package/dist/components/ui/badge.js +96 -2
  62. package/dist/components/ui/badge.js.map +1 -1
  63. package/dist/components/ui/breadcrumb.cjs +100 -0
  64. package/dist/components/ui/breadcrumb.cjs.map +1 -0
  65. package/dist/components/ui/breadcrumb.d.cts +35 -0
  66. package/dist/components/ui/breadcrumb.d.ts +35 -0
  67. package/dist/components/ui/breadcrumb.js +92 -0
  68. package/dist/components/ui/breadcrumb.js.map +1 -0
  69. package/dist/components/ui/button.cjs +304 -11
  70. package/dist/components/ui/button.cjs.map +1 -1
  71. package/dist/components/ui/button.d.cts +3 -3
  72. package/dist/components/ui/button.d.ts +3 -3
  73. package/dist/components/ui/button.js +306 -3
  74. package/dist/components/ui/button.js.map +1 -1
  75. package/dist/components/ui/calendar.cjs +401 -8
  76. package/dist/components/ui/calendar.cjs.map +1 -1
  77. package/dist/components/ui/calendar.js +404 -4
  78. package/dist/components/ui/calendar.js.map +1 -1
  79. package/dist/components/ui/card.cjs +154 -30
  80. package/dist/components/ui/card.cjs.map +1 -1
  81. package/dist/components/ui/card.js +131 -2
  82. package/dist/components/ui/card.js.map +1 -1
  83. package/dist/{chunk-CAJKSTXX.cjs → components/ui/checkbox.cjs} +10 -5
  84. package/dist/components/ui/checkbox.cjs.map +1 -0
  85. package/dist/components/ui/checkbox.d.cts +6 -0
  86. package/dist/components/ui/checkbox.d.ts +6 -0
  87. package/dist/{chunk-5JJSRGJD.js → components/ui/checkbox.js} +9 -4
  88. package/dist/components/ui/checkbox.js.map +1 -0
  89. package/dist/components/ui/concept-card.cjs +728 -11
  90. package/dist/components/ui/concept-card.cjs.map +1 -1
  91. package/dist/components/ui/concept-card.d.cts +2 -2
  92. package/dist/components/ui/concept-card.d.ts +2 -2
  93. package/dist/components/ui/concept-card.js +710 -7
  94. package/dist/components/ui/concept-card.js.map +1 -1
  95. package/dist/components/ui/data-table.cjs +1553 -10
  96. package/dist/components/ui/data-table.cjs.map +1 -1
  97. package/dist/components/ui/data-table.js +1537 -7
  98. package/dist/components/ui/data-table.js.map +1 -1
  99. package/dist/components/ui/dialog.cjs +119 -42
  100. package/dist/components/ui/dialog.cjs.map +1 -1
  101. package/dist/components/ui/dialog.js +92 -2
  102. package/dist/components/ui/dialog.js.map +1 -1
  103. package/dist/components/ui/dropdown-menu.cjs +268 -0
  104. package/dist/components/ui/dropdown-menu.cjs.map +1 -0
  105. package/dist/components/ui/dropdown-menu.d.cts +73 -0
  106. package/dist/components/ui/dropdown-menu.d.ts +73 -0
  107. package/dist/components/ui/dropdown-menu.js +232 -0
  108. package/dist/components/ui/dropdown-menu.js.map +1 -0
  109. package/dist/components/ui/filter-provider.cjs +70 -13
  110. package/dist/components/ui/filter-provider.cjs.map +1 -1
  111. package/dist/components/ui/filter-provider.js +51 -1
  112. package/dist/components/ui/filter-provider.js.map +1 -1
  113. package/dist/components/ui/form.cjs +169 -0
  114. package/dist/components/ui/form.cjs.map +1 -0
  115. package/dist/components/ui/form.d.cts +46 -0
  116. package/dist/components/ui/form.d.ts +46 -0
  117. package/dist/components/ui/form.js +139 -0
  118. package/dist/components/ui/form.js.map +1 -0
  119. package/dist/components/ui/input.cjs +135 -15
  120. package/dist/components/ui/input.cjs.map +1 -1
  121. package/dist/components/ui/input.d.cts +15 -0
  122. package/dist/components/ui/input.d.ts +15 -0
  123. package/dist/components/ui/input.js +116 -3
  124. package/dist/components/ui/input.js.map +1 -1
  125. package/dist/components/ui/iran-province-heat.cjs +328 -5
  126. package/dist/components/ui/iran-province-heat.cjs.map +1 -1
  127. package/dist/components/ui/iran-province-heat.js +312 -2
  128. package/dist/components/ui/iran-province-heat.js.map +1 -1
  129. package/dist/components/ui/label.cjs +52 -0
  130. package/dist/components/ui/label.cjs.map +1 -0
  131. package/dist/components/ui/label.d.cts +10 -0
  132. package/dist/components/ui/label.d.ts +10 -0
  133. package/dist/components/ui/label.js +30 -0
  134. package/dist/components/ui/label.js.map +1 -0
  135. package/dist/components/ui/page-card.cjs +627 -8
  136. package/dist/components/ui/page-card.cjs.map +1 -1
  137. package/dist/components/ui/page-card.d.cts +3 -2
  138. package/dist/components/ui/page-card.d.ts +3 -2
  139. package/dist/components/ui/page-card.js +611 -5
  140. package/dist/components/ui/page-card.js.map +1 -1
  141. package/dist/components/ui/page-header.cjs +299 -0
  142. package/dist/components/ui/page-header.cjs.map +1 -0
  143. package/dist/components/ui/page-header.d.cts +21 -0
  144. package/dist/components/ui/page-header.d.ts +21 -0
  145. package/dist/components/ui/page-header.js +277 -0
  146. package/dist/components/ui/page-header.js.map +1 -0
  147. package/dist/components/ui/password-input.cjs +168 -0
  148. package/dist/components/ui/password-input.cjs.map +1 -0
  149. package/dist/components/ui/password-input.d.cts +48 -0
  150. package/dist/components/ui/password-input.d.ts +48 -0
  151. package/dist/components/ui/password-input.js +146 -0
  152. package/dist/components/ui/password-input.js.map +1 -0
  153. package/dist/components/ui/popover.cjs +51 -18
  154. package/dist/components/ui/popover.cjs.map +1 -1
  155. package/dist/components/ui/popover.js +30 -2
  156. package/dist/components/ui/popover.js.map +1 -1
  157. package/dist/components/ui/progress.cjs +95 -0
  158. package/dist/components/ui/progress.cjs.map +1 -0
  159. package/dist/components/ui/progress.d.cts +18 -0
  160. package/dist/components/ui/progress.d.ts +18 -0
  161. package/dist/components/ui/progress.js +72 -0
  162. package/dist/components/ui/progress.js.map +1 -0
  163. package/dist/components/ui/radio-card.cjs +84 -0
  164. package/dist/components/ui/radio-card.cjs.map +1 -0
  165. package/dist/components/ui/radio-card.d.cts +12 -0
  166. package/dist/components/ui/radio-card.d.ts +12 -0
  167. package/dist/components/ui/radio-card.js +58 -0
  168. package/dist/components/ui/radio-card.js.map +1 -0
  169. package/dist/components/ui/radio-group.cjs +62 -0
  170. package/dist/components/ui/radio-group.cjs.map +1 -0
  171. package/dist/components/ui/radio-group.d.cts +7 -0
  172. package/dist/components/ui/radio-group.d.ts +7 -0
  173. package/dist/components/ui/radio-group.js +38 -0
  174. package/dist/components/ui/radio-group.js.map +1 -0
  175. package/dist/components/ui/saved-query-card.cjs +409 -7
  176. package/dist/components/ui/saved-query-card.cjs.map +1 -1
  177. package/dist/components/ui/saved-query-card.js +394 -4
  178. package/dist/components/ui/saved-query-card.js.map +1 -1
  179. package/dist/components/ui/scroll-area.cjs +79 -0
  180. package/dist/components/ui/scroll-area.cjs.map +1 -0
  181. package/dist/components/ui/scroll-area.d.cts +14 -0
  182. package/dist/components/ui/scroll-area.d.ts +14 -0
  183. package/dist/components/ui/scroll-area.js +56 -0
  184. package/dist/components/ui/scroll-area.js.map +1 -0
  185. package/dist/components/ui/select.cjs +242 -0
  186. package/dist/components/ui/select.cjs.map +1 -0
  187. package/dist/components/ui/select.d.cts +29 -0
  188. package/dist/components/ui/select.d.ts +29 -0
  189. package/dist/components/ui/select.js +210 -0
  190. package/dist/components/ui/select.js.map +1 -0
  191. package/dist/components/ui/separator.cjs +105 -6
  192. package/dist/components/ui/separator.cjs.map +1 -1
  193. package/dist/components/ui/separator.js +87 -2
  194. package/dist/components/ui/separator.js.map +1 -1
  195. package/dist/components/ui/sheet.cjs +134 -38
  196. package/dist/components/ui/sheet.cjs.map +1 -1
  197. package/dist/components/ui/sheet.js +109 -2
  198. package/dist/components/ui/sheet.js.map +1 -1
  199. package/dist/{chunk-D2EBLE2B.cjs → components/ui/skeleton.cjs} +21 -16
  200. package/dist/components/ui/skeleton.cjs.map +1 -0
  201. package/dist/components/ui/skeleton.d.cts +90 -0
  202. package/dist/components/ui/skeleton.d.ts +90 -0
  203. package/dist/{chunk-SB5DSYR5.js → components/ui/skeleton.js} +8 -3
  204. package/dist/components/ui/skeleton.js.map +1 -0
  205. package/dist/components/ui/slider.cjs +129 -0
  206. package/dist/components/ui/slider.cjs.map +1 -0
  207. package/dist/components/ui/slider.d.cts +10 -0
  208. package/dist/components/ui/slider.d.ts +10 -0
  209. package/dist/components/ui/slider.js +107 -0
  210. package/dist/components/ui/slider.js.map +1 -0
  211. package/dist/components/ui/social-platform-badge.cjs +120 -0
  212. package/dist/components/ui/social-platform-badge.cjs.map +1 -0
  213. package/dist/components/ui/social-platform-badge.d.cts +21 -0
  214. package/dist/components/ui/social-platform-badge.d.ts +21 -0
  215. package/dist/components/ui/social-platform-badge.js +97 -0
  216. package/dist/components/ui/social-platform-badge.js.map +1 -0
  217. package/dist/components/ui/sonner.cjs +51 -0
  218. package/dist/components/ui/sonner.cjs.map +1 -0
  219. package/dist/components/ui/sonner.d.cts +13 -0
  220. package/dist/components/ui/sonner.d.ts +13 -0
  221. package/dist/components/ui/sonner.js +45 -0
  222. package/dist/components/ui/sonner.js.map +1 -0
  223. package/dist/components/ui/sparkline.cjs +159 -6
  224. package/dist/components/ui/sparkline.cjs.map +1 -1
  225. package/dist/components/ui/sparkline.js +142 -2
  226. package/dist/components/ui/sparkline.js.map +1 -1
  227. package/dist/components/ui/switch.cjs +96 -0
  228. package/dist/components/ui/switch.cjs.map +1 -0
  229. package/dist/components/ui/switch.d.cts +13 -0
  230. package/dist/components/ui/switch.d.ts +13 -0
  231. package/dist/components/ui/switch.js +73 -0
  232. package/dist/components/ui/switch.js.map +1 -0
  233. package/dist/components/ui/table.cjs +188 -0
  234. package/dist/components/ui/table.cjs.map +1 -0
  235. package/dist/components/ui/table.d.cts +59 -0
  236. package/dist/components/ui/table.d.ts +59 -0
  237. package/dist/components/ui/table.js +178 -0
  238. package/dist/components/ui/table.js.map +1 -0
  239. package/dist/components/ui/tabs.cjs +140 -0
  240. package/dist/components/ui/tabs.cjs.map +1 -0
  241. package/dist/components/ui/tabs.d.cts +21 -0
  242. package/dist/components/ui/tabs.d.ts +21 -0
  243. package/dist/components/ui/tabs.js +115 -0
  244. package/dist/components/ui/tabs.js.map +1 -0
  245. package/dist/components/ui/textarea.cjs +56 -0
  246. package/dist/components/ui/textarea.cjs.map +1 -0
  247. package/dist/components/ui/textarea.d.cts +5 -0
  248. package/dist/components/ui/textarea.d.ts +5 -0
  249. package/dist/components/ui/textarea.js +34 -0
  250. package/dist/components/ui/textarea.js.map +1 -0
  251. package/dist/components/ui/toggle-group.cjs +123 -0
  252. package/dist/components/ui/toggle-group.cjs.map +1 -0
  253. package/dist/components/ui/toggle-group.d.cts +7 -0
  254. package/dist/components/ui/toggle-group.d.ts +7 -0
  255. package/dist/components/ui/toggle-group.js +99 -0
  256. package/dist/components/ui/toggle-group.js.map +1 -0
  257. package/dist/components/ui/tooltip.cjs +77 -18
  258. package/dist/components/ui/tooltip.cjs.map +1 -1
  259. package/dist/components/ui/tooltip.js +56 -2
  260. package/dist/components/ui/tooltip.js.map +1 -1
  261. package/dist/{concept-card-RwPbqJ06.d.cts → concept-card-BXra9mr0.d.cts} +2 -2
  262. package/dist/{concept-card-CcOBb2Nz.d.ts → concept-card-BoJ5gIJD.d.ts} +2 -2
  263. package/dist/hooks/use-hotkey-registry.cjs +201 -14
  264. package/dist/hooks/use-hotkey-registry.cjs.map +1 -1
  265. package/dist/hooks/use-hotkey-registry.js +182 -2
  266. package/dist/hooks/use-hotkey-registry.js.map +1 -1
  267. package/dist/hooks/use-hotkeys.cjs +144 -9
  268. package/dist/hooks/use-hotkeys.cjs.map +1 -1
  269. package/dist/hooks/use-hotkeys.js +126 -1
  270. package/dist/hooks/use-hotkeys.js.map +1 -1
  271. package/dist/{i18n-CAd9wGOr.d.cts → i18n-BfRhV5aw.d.cts} +5 -3
  272. package/dist/{i18n-ArS3mqj0.d.ts → i18n-ewyqbKM-.d.ts} +5 -3
  273. package/dist/index.cjs +20906 -15706
  274. package/dist/index.cjs.map +1 -1
  275. package/dist/index.css +396 -69
  276. package/dist/index.d.cts +49 -490
  277. package/dist/index.d.ts +49 -490
  278. package/dist/index.js +7704 -2032
  279. package/dist/index.js.map +1 -1
  280. package/dist/{page-card-CmShVqG-.d.cts → page-card-C9XXXOVr.d.cts} +3 -20
  281. package/dist/{page-card-HBn-cy4J.d.ts → page-card-DAnbez_f.d.ts} +3 -20
  282. package/dist/toggle-group-B8r4LOQw.d.cts +26 -0
  283. package/dist/toggle-group-B8r4LOQw.d.ts +26 -0
  284. package/package.json +132 -2
  285. package/tailwind.config.ts +45 -0
  286. package/dist/chunk-2ACKKPWA.cjs +0 -112
  287. package/dist/chunk-2ACKKPWA.cjs.map +0 -1
  288. package/dist/chunk-2UD3LGVX.cjs +0 -316
  289. package/dist/chunk-2UD3LGVX.cjs.map +0 -1
  290. package/dist/chunk-3QYYPPFJ.js.map +0 -1
  291. package/dist/chunk-4SVQNEVH.js +0 -173
  292. package/dist/chunk-4SVQNEVH.js.map +0 -1
  293. package/dist/chunk-4WONHORR.cjs +0 -152
  294. package/dist/chunk-4WONHORR.cjs.map +0 -1
  295. package/dist/chunk-5HCXH6GS.js +0 -409
  296. package/dist/chunk-5HCXH6GS.js.map +0 -1
  297. package/dist/chunk-5JJSRGJD.js.map +0 -1
  298. package/dist/chunk-5K6E4ZSW.cjs +0 -77
  299. package/dist/chunk-5K6E4ZSW.cjs.map +0 -1
  300. package/dist/chunk-5NY26ULO.js +0 -89
  301. package/dist/chunk-5NY26ULO.js.map +0 -1
  302. package/dist/chunk-7RVPG3LE.cjs +0 -231
  303. package/dist/chunk-7RVPG3LE.cjs.map +0 -1
  304. package/dist/chunk-AYEK3WOM.js +0 -207
  305. package/dist/chunk-AYEK3WOM.js.map +0 -1
  306. package/dist/chunk-BRMBLIQG.js +0 -53
  307. package/dist/chunk-BRMBLIQG.js.map +0 -1
  308. package/dist/chunk-CAJKSTXX.cjs.map +0 -1
  309. package/dist/chunk-CKFWMHQU.js +0 -401
  310. package/dist/chunk-CKFWMHQU.js.map +0 -1
  311. package/dist/chunk-CV3N3HVK.js +0 -672
  312. package/dist/chunk-CV3N3HVK.js.map +0 -1
  313. package/dist/chunk-D2EBLE2B.cjs.map +0 -1
  314. package/dist/chunk-GCZ6YATL.js +0 -940
  315. package/dist/chunk-GCZ6YATL.js.map +0 -1
  316. package/dist/chunk-GKRAZGDI.cjs +0 -84
  317. package/dist/chunk-GKRAZGDI.cjs.map +0 -1
  318. package/dist/chunk-GPYJ66CG.js +0 -45
  319. package/dist/chunk-GPYJ66CG.js.map +0 -1
  320. package/dist/chunk-HF6XU5NI.js +0 -84
  321. package/dist/chunk-HF6XU5NI.js.map +0 -1
  322. package/dist/chunk-HJPDZOMJ.cjs +0 -87
  323. package/dist/chunk-HJPDZOMJ.cjs.map +0 -1
  324. package/dist/chunk-HS3XI3CC.cjs +0 -69
  325. package/dist/chunk-HS3XI3CC.cjs.map +0 -1
  326. package/dist/chunk-HUCC3QH5.cjs +0 -53
  327. package/dist/chunk-HUCC3QH5.cjs.map +0 -1
  328. package/dist/chunk-HYZ6BQPS.cjs +0 -425
  329. package/dist/chunk-HYZ6BQPS.cjs.map +0 -1
  330. package/dist/chunk-ISCSZMYW.cjs +0 -106
  331. package/dist/chunk-ISCSZMYW.cjs.map +0 -1
  332. package/dist/chunk-IXFEFIDO.js +0 -82
  333. package/dist/chunk-IXFEFIDO.js.map +0 -1
  334. package/dist/chunk-JCJLN437.js +0 -108
  335. package/dist/chunk-JCJLN437.js.map +0 -1
  336. package/dist/chunk-JMKNNH63.cjs +0 -982
  337. package/dist/chunk-JMKNNH63.cjs.map +0 -1
  338. package/dist/chunk-JUBHQAA2.js +0 -53
  339. package/dist/chunk-JUBHQAA2.js.map +0 -1
  340. package/dist/chunk-K6G63EED.cjs +0 -41
  341. package/dist/chunk-K6G63EED.cjs.map +0 -1
  342. package/dist/chunk-KCWRCSI7.js +0 -62
  343. package/dist/chunk-KCWRCSI7.js.map +0 -1
  344. package/dist/chunk-KYM7NIJO.cjs +0 -433
  345. package/dist/chunk-KYM7NIJO.cjs.map +0 -1
  346. package/dist/chunk-L2L5CKC2.js +0 -291
  347. package/dist/chunk-L2L5CKC2.js.map +0 -1
  348. package/dist/chunk-M5CHZ5BA.js +0 -124
  349. package/dist/chunk-M5CHZ5BA.js.map +0 -1
  350. package/dist/chunk-MEK4RSGC.js +0 -65
  351. package/dist/chunk-MEK4RSGC.js.map +0 -1
  352. package/dist/chunk-MEKWH3GS.js +0 -89
  353. package/dist/chunk-MEKWH3GS.js.map +0 -1
  354. package/dist/chunk-MFTX2DDQ.js +0 -27
  355. package/dist/chunk-MFTX2DDQ.js.map +0 -1
  356. package/dist/chunk-MMC6M35Q.cjs.map +0 -1
  357. package/dist/chunk-NMH43BDC.js +0 -130
  358. package/dist/chunk-NMH43BDC.js.map +0 -1
  359. package/dist/chunk-NORDUD2T.cjs +0 -135
  360. package/dist/chunk-NORDUD2T.cjs.map +0 -1
  361. package/dist/chunk-NV4JOKWL.cjs +0 -197
  362. package/dist/chunk-NV4JOKWL.cjs.map +0 -1
  363. package/dist/chunk-O2JG7WY5.cjs +0 -121
  364. package/dist/chunk-O2JG7WY5.cjs.map +0 -1
  365. package/dist/chunk-ONO2FTV4.cjs +0 -68
  366. package/dist/chunk-ONO2FTV4.cjs.map +0 -1
  367. package/dist/chunk-OQB6HIUL.cjs +0 -108
  368. package/dist/chunk-OQB6HIUL.cjs.map +0 -1
  369. package/dist/chunk-OS6CMYAS.cjs +0 -79
  370. package/dist/chunk-OS6CMYAS.cjs.map +0 -1
  371. package/dist/chunk-PYURPUTV.js +0 -402
  372. package/dist/chunk-PYURPUTV.js.map +0 -1
  373. package/dist/chunk-RJ3HYZ7S.js +0 -44
  374. package/dist/chunk-RJ3HYZ7S.js.map +0 -1
  375. package/dist/chunk-RZNRIOLT.js +0 -128
  376. package/dist/chunk-RZNRIOLT.js.map +0 -1
  377. package/dist/chunk-S3T2L6NA.js +0 -38
  378. package/dist/chunk-S3T2L6NA.js.map +0 -1
  379. package/dist/chunk-S5IPJQZ3.cjs +0 -161
  380. package/dist/chunk-S5IPJQZ3.cjs.map +0 -1
  381. package/dist/chunk-SB5DSYR5.js.map +0 -1
  382. package/dist/chunk-SFXV2DUH.js +0 -106
  383. package/dist/chunk-SFXV2DUH.js.map +0 -1
  384. package/dist/chunk-SXEPGD4Z.cjs +0 -152
  385. package/dist/chunk-SXEPGD4Z.cjs.map +0 -1
  386. package/dist/chunk-SXWSOU3Y.js +0 -89
  387. package/dist/chunk-SXWSOU3Y.js.map +0 -1
  388. package/dist/chunk-SZMVOHT7.cjs +0 -107
  389. package/dist/chunk-SZMVOHT7.cjs.map +0 -1
  390. package/dist/chunk-TWJXOV4C.js +0 -145
  391. package/dist/chunk-TWJXOV4C.js.map +0 -1
  392. package/dist/chunk-U3ADRIVO.cjs +0 -434
  393. package/dist/chunk-U3ADRIVO.cjs.map +0 -1
  394. package/dist/chunk-U5FLLCGC.cjs +0 -151
  395. package/dist/chunk-U5FLLCGC.cjs.map +0 -1
  396. package/dist/chunk-UOZN45G4.cjs +0 -130
  397. package/dist/chunk-UOZN45G4.cjs.map +0 -1
  398. package/dist/chunk-VHLDOG74.cjs +0 -167
  399. package/dist/chunk-VHLDOG74.cjs.map +0 -1
  400. package/dist/chunk-YC5KLN6I.js +0 -139
  401. package/dist/chunk-YC5KLN6I.js.map +0 -1
  402. package/dist/chunk-YENXXYUV.cjs +0 -111
  403. package/dist/chunk-YENXXYUV.cjs.map +0 -1
  404. package/dist/chunk-YFQWC2PW.js +0 -113
  405. package/dist/chunk-YFQWC2PW.js.map +0 -1
  406. package/dist/chunk-Z2TY4A75.cjs +0 -700
  407. package/dist/chunk-Z2TY4A75.cjs.map +0 -1
  408. package/dist/chunk-Z56O7UEU.cjs +0 -136
  409. package/dist/chunk-Z56O7UEU.cjs.map +0 -1
  410. package/dist/chunk-ZBZDR4ZC.js +0 -106
  411. 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":"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","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":"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","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"]}