@parto-system-design/ui 1.1.5 → 1.1.7

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 (301) hide show
  1. package/AGENTS.md +233 -0
  2. package/LICENSE +21 -0
  3. package/README.md +96 -43
  4. package/dist/chunk-2UD3LGVX.cjs +316 -0
  5. package/dist/chunk-2UD3LGVX.cjs.map +1 -0
  6. package/dist/chunk-34JUCX2G.cjs +43 -0
  7. package/dist/chunk-34JUCX2G.cjs.map +1 -0
  8. package/dist/chunk-3AIJKXBV.cjs +242 -0
  9. package/dist/chunk-3AIJKXBV.cjs.map +1 -0
  10. package/dist/chunk-4SVQNEVH.js +173 -0
  11. package/dist/chunk-4SVQNEVH.js.map +1 -0
  12. package/dist/chunk-53QY4PD3.js +908 -0
  13. package/dist/chunk-53QY4PD3.js.map +1 -0
  14. package/dist/chunk-5JJSRGJD.js +31 -0
  15. package/dist/chunk-5JJSRGJD.js.map +1 -0
  16. package/dist/chunk-5K6E4ZSW.cjs +77 -0
  17. package/dist/chunk-5K6E4ZSW.cjs.map +1 -0
  18. package/dist/chunk-5NY26ULO.js +89 -0
  19. package/dist/chunk-5NY26ULO.js.map +1 -0
  20. package/dist/chunk-7RVPG3LE.cjs +231 -0
  21. package/dist/chunk-7RVPG3LE.cjs.map +1 -0
  22. package/dist/chunk-7Y4V3R3Y.cjs +120 -0
  23. package/dist/chunk-7Y4V3R3Y.cjs.map +1 -0
  24. package/dist/chunk-AXAY64KL.js +39 -0
  25. package/dist/chunk-AXAY64KL.js.map +1 -0
  26. package/dist/chunk-AYEK3WOM.js +207 -0
  27. package/dist/chunk-AYEK3WOM.js.map +1 -0
  28. package/dist/chunk-BRMBLIQG.js +53 -0
  29. package/dist/chunk-BRMBLIQG.js.map +1 -0
  30. package/dist/chunk-CAJKSTXX.cjs +54 -0
  31. package/dist/chunk-CAJKSTXX.cjs.map +1 -0
  32. package/dist/chunk-CKFWMHQU.js +401 -0
  33. package/dist/chunk-CKFWMHQU.js.map +1 -0
  34. package/dist/chunk-CV3N3HVK.js +672 -0
  35. package/dist/chunk-CV3N3HVK.js.map +1 -0
  36. package/dist/chunk-D2EBLE2B.cjs +220 -0
  37. package/dist/chunk-D2EBLE2B.cjs.map +1 -0
  38. package/dist/chunk-D5XCQDFS.js +92 -0
  39. package/dist/chunk-D5XCQDFS.js.map +1 -0
  40. package/dist/chunk-GDHRYKVM.js +45 -0
  41. package/dist/chunk-GDHRYKVM.js.map +1 -0
  42. package/dist/chunk-GKRAZGDI.cjs +84 -0
  43. package/dist/chunk-GKRAZGDI.cjs.map +1 -0
  44. package/dist/chunk-HEYMLQOV.cjs +94 -0
  45. package/dist/chunk-HEYMLQOV.cjs.map +1 -0
  46. package/dist/chunk-HF6XU5NI.js +84 -0
  47. package/dist/chunk-HF6XU5NI.js.map +1 -0
  48. package/dist/chunk-HJPDZOMJ.cjs +87 -0
  49. package/dist/chunk-HJPDZOMJ.cjs.map +1 -0
  50. package/dist/chunk-HUCC3QH5.cjs +53 -0
  51. package/dist/chunk-HUCC3QH5.cjs.map +1 -0
  52. package/dist/chunk-HYZ6BQPS.cjs +425 -0
  53. package/dist/chunk-HYZ6BQPS.cjs.map +1 -0
  54. package/dist/chunk-IQHKJ4SS.js +213 -0
  55. package/dist/chunk-IQHKJ4SS.js.map +1 -0
  56. package/dist/chunk-ISCSZMYW.cjs +106 -0
  57. package/dist/chunk-ISCSZMYW.cjs.map +1 -0
  58. package/dist/chunk-IXFEFIDO.js +82 -0
  59. package/dist/chunk-IXFEFIDO.js.map +1 -0
  60. package/dist/chunk-JUBHQAA2.js +53 -0
  61. package/dist/chunk-JUBHQAA2.js.map +1 -0
  62. package/dist/chunk-KCWRCSI7.js +62 -0
  63. package/dist/chunk-KCWRCSI7.js.map +1 -0
  64. package/dist/chunk-L2L5CKC2.js +291 -0
  65. package/dist/chunk-L2L5CKC2.js.map +1 -0
  66. package/dist/chunk-LLJR7FV3.js +135 -0
  67. package/dist/chunk-LLJR7FV3.js.map +1 -0
  68. package/dist/chunk-LZMCMZZF.js +118 -0
  69. package/dist/chunk-LZMCMZZF.js.map +1 -0
  70. package/dist/chunk-M5CHZ5BA.js +124 -0
  71. package/dist/chunk-M5CHZ5BA.js.map +1 -0
  72. package/dist/chunk-MBCTRNTG.js +89 -0
  73. package/dist/chunk-MBCTRNTG.js.map +1 -0
  74. package/dist/chunk-MEK4RSGC.js +65 -0
  75. package/dist/chunk-MEK4RSGC.js.map +1 -0
  76. package/dist/chunk-MFTX2DDQ.js +27 -0
  77. package/dist/chunk-MFTX2DDQ.js.map +1 -0
  78. package/dist/chunk-MKYVQQBV.cjs +114 -0
  79. package/dist/chunk-MKYVQQBV.cjs.map +1 -0
  80. package/dist/chunk-MQGQVI3W.cjs +950 -0
  81. package/dist/chunk-MQGQVI3W.cjs.map +1 -0
  82. package/dist/chunk-NEFZJHE4.cjs +157 -0
  83. package/dist/chunk-NEFZJHE4.cjs.map +1 -0
  84. package/dist/chunk-NEML6RCV.js +405 -0
  85. package/dist/chunk-NEML6RCV.js.map +1 -0
  86. package/dist/chunk-NV4JOKWL.cjs +197 -0
  87. package/dist/chunk-NV4JOKWL.cjs.map +1 -0
  88. package/dist/chunk-O2JG7WY5.cjs +121 -0
  89. package/dist/chunk-O2JG7WY5.cjs.map +1 -0
  90. package/dist/chunk-OEVMKFFL.cjs +140 -0
  91. package/dist/chunk-OEVMKFFL.cjs.map +1 -0
  92. package/dist/chunk-ONO2FTV4.cjs +68 -0
  93. package/dist/chunk-ONO2FTV4.cjs.map +1 -0
  94. package/dist/chunk-OS6CMYAS.cjs +79 -0
  95. package/dist/chunk-OS6CMYAS.cjs.map +1 -0
  96. package/dist/chunk-P5XHPNJG.cjs +430 -0
  97. package/dist/chunk-P5XHPNJG.cjs.map +1 -0
  98. package/dist/chunk-QJ7UB2ZQ.js +98 -0
  99. package/dist/chunk-QJ7UB2ZQ.js.map +1 -0
  100. package/dist/chunk-RA5KZNG5.js +269 -0
  101. package/dist/chunk-RA5KZNG5.js.map +1 -0
  102. package/dist/chunk-RJ3HYZ7S.js +44 -0
  103. package/dist/chunk-RJ3HYZ7S.js.map +1 -0
  104. package/dist/chunk-RZNRIOLT.js +128 -0
  105. package/dist/chunk-RZNRIOLT.js.map +1 -0
  106. package/dist/chunk-S5IPJQZ3.cjs +161 -0
  107. package/dist/chunk-S5IPJQZ3.cjs.map +1 -0
  108. package/dist/chunk-SB5DSYR5.js +211 -0
  109. package/dist/chunk-SB5DSYR5.js.map +1 -0
  110. package/dist/chunk-SCGW2BH4.cjs +69 -0
  111. package/dist/chunk-SCGW2BH4.cjs.map +1 -0
  112. package/dist/chunk-SCX6AR53.cjs +108 -0
  113. package/dist/chunk-SCX6AR53.cjs.map +1 -0
  114. package/dist/chunk-SFXV2DUH.js +106 -0
  115. package/dist/chunk-SFXV2DUH.js.map +1 -0
  116. package/dist/chunk-SXEPGD4Z.cjs +152 -0
  117. package/dist/chunk-SXEPGD4Z.cjs.map +1 -0
  118. package/dist/chunk-SZMVOHT7.cjs +107 -0
  119. package/dist/chunk-SZMVOHT7.cjs.map +1 -0
  120. package/dist/chunk-U5FLLCGC.cjs +151 -0
  121. package/dist/chunk-U5FLLCGC.cjs.map +1 -0
  122. package/dist/chunk-VO3B75F6.cjs +111 -0
  123. package/dist/chunk-VO3B75F6.cjs.map +1 -0
  124. package/dist/chunk-YAJWTNOX.js +106 -0
  125. package/dist/chunk-YAJWTNOX.js.map +1 -0
  126. package/dist/chunk-YC5KLN6I.js +139 -0
  127. package/dist/chunk-YC5KLN6I.js.map +1 -0
  128. package/dist/chunk-YE477L2H.cjs +272 -0
  129. package/dist/chunk-YE477L2H.cjs.map +1 -0
  130. package/dist/chunk-Z2TY4A75.cjs +700 -0
  131. package/dist/chunk-Z2TY4A75.cjs.map +1 -0
  132. package/dist/chunk-Z56O7UEU.cjs +136 -0
  133. package/dist/chunk-Z56O7UEU.cjs.map +1 -0
  134. package/dist/chunk-ZZFNJR2E.js +71 -0
  135. package/dist/chunk-ZZFNJR2E.js.map +1 -0
  136. package/dist/components/charts/PartoAreaChart.cjs +15 -0
  137. package/dist/components/charts/PartoAreaChart.cjs.map +1 -0
  138. package/dist/components/charts/PartoAreaChart.d.cts +51 -0
  139. package/dist/components/charts/PartoAreaChart.d.ts +51 -0
  140. package/dist/components/charts/PartoAreaChart.js +6 -0
  141. package/dist/components/charts/PartoAreaChart.js.map +1 -0
  142. package/dist/components/charts/PartoBarChart.cjs +15 -0
  143. package/dist/components/charts/PartoBarChart.cjs.map +1 -0
  144. package/dist/components/charts/PartoBarChart.d.cts +55 -0
  145. package/dist/components/charts/PartoBarChart.d.ts +55 -0
  146. package/dist/components/charts/PartoBarChart.js +6 -0
  147. package/dist/components/charts/PartoBarChart.js.map +1 -0
  148. package/dist/components/charts/PartoLineChart.cjs +15 -0
  149. package/dist/components/charts/PartoLineChart.cjs.map +1 -0
  150. package/dist/components/charts/PartoLineChart.d.cts +49 -0
  151. package/dist/components/charts/PartoLineChart.d.ts +49 -0
  152. package/dist/components/charts/PartoLineChart.js +6 -0
  153. package/dist/components/charts/PartoLineChart.js.map +1 -0
  154. package/dist/components/charts/PartoPieChart.cjs +15 -0
  155. package/dist/components/charts/PartoPieChart.cjs.map +1 -0
  156. package/dist/components/charts/PartoPieChart.d.cts +44 -0
  157. package/dist/components/charts/PartoPieChart.d.ts +44 -0
  158. package/dist/components/charts/PartoPieChart.js +6 -0
  159. package/dist/components/charts/PartoPieChart.js.map +1 -0
  160. package/dist/components/ui/alert-rule-card.cjs +15 -0
  161. package/dist/components/ui/alert-rule-card.cjs.map +1 -0
  162. package/dist/components/ui/alert-rule-card.d.cts +38 -0
  163. package/dist/components/ui/alert-rule-card.d.ts +38 -0
  164. package/dist/components/ui/alert-rule-card.js +6 -0
  165. package/dist/components/ui/alert-rule-card.js.map +1 -0
  166. package/dist/components/ui/avatar.cjs +21 -0
  167. package/dist/components/ui/avatar.cjs.map +1 -0
  168. package/dist/components/ui/avatar.d.cts +18 -0
  169. package/dist/components/ui/avatar.d.ts +18 -0
  170. package/dist/components/ui/avatar.js +4 -0
  171. package/dist/components/ui/avatar.js.map +1 -0
  172. package/dist/components/ui/badge.cjs +17 -0
  173. package/dist/components/ui/badge.cjs.map +1 -0
  174. package/dist/components/ui/badge.d.cts +16 -0
  175. package/dist/components/ui/badge.d.ts +16 -0
  176. package/dist/components/ui/badge.js +4 -0
  177. package/dist/components/ui/badge.js.map +1 -0
  178. package/dist/components/ui/button.cjs +18 -0
  179. package/dist/components/ui/button.cjs.map +1 -0
  180. package/dist/components/ui/button.d.cts +37 -0
  181. package/dist/components/ui/button.d.ts +37 -0
  182. package/dist/components/ui/button.js +5 -0
  183. package/dist/components/ui/button.js.map +1 -0
  184. package/dist/components/ui/calendar.cjs +15 -0
  185. package/dist/components/ui/calendar.cjs.map +1 -0
  186. package/dist/components/ui/calendar.d.cts +17 -0
  187. package/dist/components/ui/calendar.d.ts +17 -0
  188. package/dist/components/ui/calendar.js +6 -0
  189. package/dist/components/ui/calendar.js.map +1 -0
  190. package/dist/components/ui/card.cjs +37 -0
  191. package/dist/components/ui/card.cjs.map +1 -0
  192. package/dist/components/ui/card.d.cts +18 -0
  193. package/dist/components/ui/card.d.ts +18 -0
  194. package/dist/components/ui/card.js +4 -0
  195. package/dist/components/ui/card.js.map +1 -0
  196. package/dist/components/ui/concept-card.cjs +18 -0
  197. package/dist/components/ui/concept-card.cjs.map +1 -0
  198. package/dist/components/ui/concept-card.d.cts +5 -0
  199. package/dist/components/ui/concept-card.d.ts +5 -0
  200. package/dist/components/ui/concept-card.js +9 -0
  201. package/dist/components/ui/concept-card.js.map +1 -0
  202. package/dist/components/ui/data-table.cjs +18 -0
  203. package/dist/components/ui/data-table.cjs.map +1 -0
  204. package/dist/components/ui/data-table.d.cts +181 -0
  205. package/dist/components/ui/data-table.d.ts +181 -0
  206. package/dist/components/ui/data-table.js +9 -0
  207. package/dist/components/ui/data-table.js.map +1 -0
  208. package/dist/components/ui/dialog.cjs +49 -0
  209. package/dist/components/ui/dialog.cjs.map +1 -0
  210. package/dist/components/ui/dialog.d.cts +22 -0
  211. package/dist/components/ui/dialog.d.ts +22 -0
  212. package/dist/components/ui/dialog.js +4 -0
  213. package/dist/components/ui/dialog.js.map +1 -0
  214. package/dist/components/ui/filter-provider.cjs +20 -0
  215. package/dist/components/ui/filter-provider.cjs.map +1 -0
  216. package/dist/components/ui/filter-provider.d.cts +49 -0
  217. package/dist/components/ui/filter-provider.d.ts +49 -0
  218. package/dist/components/ui/filter-provider.js +3 -0
  219. package/dist/components/ui/filter-provider.js.map +1 -0
  220. package/dist/components/ui/input.cjs +22 -0
  221. package/dist/components/ui/input.cjs.map +1 -0
  222. package/dist/components/ui/input.d.cts +16 -0
  223. package/dist/components/ui/input.d.ts +16 -0
  224. package/dist/components/ui/input.js +5 -0
  225. package/dist/components/ui/input.js.map +1 -0
  226. package/dist/components/ui/iran-province-heat.cjs +13 -0
  227. package/dist/components/ui/iran-province-heat.cjs.map +1 -0
  228. package/dist/components/ui/iran-province-heat.d.cts +64 -0
  229. package/dist/components/ui/iran-province-heat.d.ts +64 -0
  230. package/dist/components/ui/iran-province-heat.js +4 -0
  231. package/dist/components/ui/iran-province-heat.js.map +1 -0
  232. package/dist/components/ui/page-card.cjs +16 -0
  233. package/dist/components/ui/page-card.cjs.map +1 -0
  234. package/dist/components/ui/page-card.d.cts +6 -0
  235. package/dist/components/ui/page-card.d.ts +6 -0
  236. package/dist/components/ui/page-card.js +7 -0
  237. package/dist/components/ui/page-card.js.map +1 -0
  238. package/dist/components/ui/popover.cjs +25 -0
  239. package/dist/components/ui/popover.cjs.map +1 -0
  240. package/dist/components/ui/popover.d.cts +9 -0
  241. package/dist/components/ui/popover.d.ts +9 -0
  242. package/dist/components/ui/popover.js +4 -0
  243. package/dist/components/ui/popover.js.map +1 -0
  244. package/dist/components/ui/saved-query-card.cjs +15 -0
  245. package/dist/components/ui/saved-query-card.cjs.map +1 -0
  246. package/dist/components/ui/saved-query-card.d.cts +41 -0
  247. package/dist/components/ui/saved-query-card.d.ts +41 -0
  248. package/dist/components/ui/saved-query-card.js +6 -0
  249. package/dist/components/ui/saved-query-card.js.map +1 -0
  250. package/dist/components/ui/separator.cjs +13 -0
  251. package/dist/components/ui/separator.cjs.map +1 -0
  252. package/dist/components/ui/separator.d.cts +9 -0
  253. package/dist/components/ui/separator.d.ts +9 -0
  254. package/dist/components/ui/separator.js +4 -0
  255. package/dist/components/ui/separator.js.map +1 -0
  256. package/dist/components/ui/sheet.cjs +45 -0
  257. package/dist/components/ui/sheet.cjs.map +1 -0
  258. package/dist/components/ui/sheet.d.cts +44 -0
  259. package/dist/components/ui/sheet.d.ts +44 -0
  260. package/dist/components/ui/sheet.js +4 -0
  261. package/dist/components/ui/sheet.js.map +1 -0
  262. package/dist/components/ui/sparkline.cjs +13 -0
  263. package/dist/components/ui/sparkline.cjs.map +1 -0
  264. package/dist/components/ui/sparkline.d.cts +36 -0
  265. package/dist/components/ui/sparkline.d.ts +36 -0
  266. package/dist/components/ui/sparkline.js +4 -0
  267. package/dist/components/ui/sparkline.js.map +1 -0
  268. package/dist/components/ui/tooltip.cjs +25 -0
  269. package/dist/components/ui/tooltip.cjs.map +1 -0
  270. package/dist/components/ui/tooltip.d.cts +17 -0
  271. package/dist/components/ui/tooltip.d.ts +17 -0
  272. package/dist/components/ui/tooltip.js +4 -0
  273. package/dist/components/ui/tooltip.js.map +1 -0
  274. package/dist/concept-card-CcOBb2Nz.d.ts +83 -0
  275. package/dist/concept-card-RwPbqJ06.d.cts +83 -0
  276. package/dist/hooks/use-hotkey-registry.cjs +21 -0
  277. package/dist/hooks/use-hotkey-registry.cjs.map +1 -0
  278. package/dist/hooks/use-hotkey-registry.d.cts +65 -0
  279. package/dist/hooks/use-hotkey-registry.d.ts +65 -0
  280. package/dist/hooks/use-hotkey-registry.js +4 -0
  281. package/dist/hooks/use-hotkey-registry.js.map +1 -0
  282. package/dist/hooks/use-hotkeys.cjs +16 -0
  283. package/dist/hooks/use-hotkeys.cjs.map +1 -0
  284. package/dist/hooks/use-hotkeys.d.cts +66 -0
  285. package/dist/hooks/use-hotkeys.d.ts +66 -0
  286. package/dist/hooks/use-hotkeys.js +3 -0
  287. package/dist/hooks/use-hotkeys.js.map +1 -0
  288. package/dist/i18n-ArS3mqj0.d.ts +344 -0
  289. package/dist/i18n-CAd9wGOr.d.cts +344 -0
  290. package/dist/index.cjs +7383 -10955
  291. package/dist/index.cjs.map +1 -1
  292. package/dist/index.css +157 -0
  293. package/dist/index.d.cts +726 -1144
  294. package/dist/index.d.ts +726 -1144
  295. package/dist/index.js +6735 -10912
  296. package/dist/index.js.map +1 -1
  297. package/dist/page-card-CO92oXkc.d.ts +100 -0
  298. package/dist/page-card-DOl50DqJ.d.cts +100 -0
  299. package/dist/utils-DlXWmDZ-.d.cts +35 -0
  300. package/dist/utils-DlXWmDZ-.d.ts +35 -0
  301. package/package.json +160 -4
@@ -0,0 +1,98 @@
1
+ import { useChartTheme, localeAwareCategoryTick, localeAwareNumberTick, ChartLoadingSkeleton, ChartContainer, ChartTooltip } from './chunk-IQHKJ4SS.js';
2
+ import * as React from 'react';
3
+ import { ResponsiveContainer, AreaChart, CartesianGrid, XAxis, YAxis, Tooltip, Area } from 'recharts';
4
+ import { jsx, jsxs } from 'react/jsx-runtime';
5
+
6
+ var PartoAreaChart = React.forwardRef(function PartoAreaChart2({
7
+ data,
8
+ dataKeys,
9
+ xAxisKey = "name",
10
+ curve = "monotone",
11
+ strokeWidth = 2,
12
+ fillOpacity = 0.08,
13
+ showDots = false,
14
+ enableGridY = true,
15
+ enableGridX = false,
16
+ margin = { top: 20, right: 20, bottom: 50, left: 50 },
17
+ axisBottom,
18
+ axisLeft,
19
+ tooltipFormatter,
20
+ locale = "fa",
21
+ className,
22
+ isLoading = false,
23
+ ariaLabel,
24
+ chartProps
25
+ }, ref) {
26
+ const { chartColors, axisTickStyle, gridStyle, tooltipStyle, crosshairStyle } = useChartTheme();
27
+ const defaultXTick = React.useMemo(() => localeAwareCategoryTick(locale), [locale]);
28
+ const defaultYTick = React.useMemo(() => localeAwareNumberTick(locale), [locale]);
29
+ if (isLoading) {
30
+ return /* @__PURE__ */ jsx(ChartLoadingSkeleton, { className });
31
+ }
32
+ return /* @__PURE__ */ jsx(ChartContainer, { ref, className, dataSlot: "area-chart", ariaLabel, children: /* @__PURE__ */ jsx(ResponsiveContainer, { width: "100%", height: "100%", children: /* @__PURE__ */ jsxs(AreaChart, { data, margin, ...chartProps, children: [
33
+ /* @__PURE__ */ jsx("defs", { children: dataKeys.map((key, i) => /* @__PURE__ */ jsxs("linearGradient", { id: `area-gradient-${key}`, x1: "0", y1: "0", x2: "0", y2: "1", children: [
34
+ /* @__PURE__ */ jsx("stop", { offset: "0%", stopColor: chartColors[i % chartColors.length], stopOpacity: fillOpacity }),
35
+ /* @__PURE__ */ jsx("stop", { offset: "100%", stopColor: chartColors[i % chartColors.length], stopOpacity: 0 })
36
+ ] }, key)) }),
37
+ (enableGridX || enableGridY) && /* @__PURE__ */ jsx(
38
+ CartesianGrid,
39
+ {
40
+ horizontal: enableGridY,
41
+ vertical: enableGridX,
42
+ stroke: gridStyle.stroke,
43
+ strokeDasharray: gridStyle.strokeDasharray,
44
+ strokeOpacity: gridStyle.strokeOpacity
45
+ }
46
+ ),
47
+ axisBottom !== null && /* @__PURE__ */ jsx(
48
+ XAxis,
49
+ {
50
+ dataKey: xAxisKey,
51
+ tick: axisTickStyle,
52
+ tickLine: false,
53
+ axisLine: false,
54
+ tickMargin: 12,
55
+ tickFormatter: defaultXTick,
56
+ ...axisBottom
57
+ }
58
+ ),
59
+ axisLeft !== null && /* @__PURE__ */ jsx(
60
+ YAxis,
61
+ {
62
+ tick: axisTickStyle,
63
+ tickLine: false,
64
+ axisLine: false,
65
+ tickMargin: 12,
66
+ tickFormatter: defaultYTick,
67
+ ...axisLeft
68
+ }
69
+ ),
70
+ /* @__PURE__ */ jsx(
71
+ Tooltip,
72
+ {
73
+ cursor: crosshairStyle,
74
+ content: /* @__PURE__ */ jsx(ChartTooltip, { tooltipStyle, formatter: tooltipFormatter, locale })
75
+ }
76
+ ),
77
+ dataKeys.map((key, i) => /* @__PURE__ */ jsx(
78
+ Area,
79
+ {
80
+ type: curve,
81
+ dataKey: key,
82
+ stroke: chartColors[i % chartColors.length],
83
+ strokeWidth,
84
+ fill: `url(#area-gradient-${key})`,
85
+ dot: showDots,
86
+ activeDot: { r: 4, strokeWidth: 2 },
87
+ animationDuration: 800,
88
+ animationEasing: "ease-out"
89
+ },
90
+ key
91
+ ))
92
+ ] }) }) });
93
+ });
94
+ PartoAreaChart.displayName = "PartoAreaChart";
95
+
96
+ export { PartoAreaChart };
97
+ //# sourceMappingURL=chunk-QJ7UB2ZQ.js.map
98
+ //# sourceMappingURL=chunk-QJ7UB2ZQ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/charts/PartoAreaChart.tsx"],"names":["PartoAreaChart"],"mappings":";;;;;AAuDO,IAAM,cAAA,GAAuB,KAAA,CAAA,UAAA,CAAgD,SAASA,eAAAA,CAC3F;AAAA,EACE,IAAA;AAAA,EACA,QAAA;AAAA,EACA,QAAA,GAAW,MAAA;AAAA,EACX,KAAA,GAAQ,UAAA;AAAA,EACR,WAAA,GAAc,CAAA;AAAA,EACd,WAAA,GAAc,IAAA;AAAA,EACd,QAAA,GAAW,KAAA;AAAA,EACX,WAAA,GAAc,IAAA;AAAA,EACd,WAAA,GAAc,KAAA;AAAA,EACd,MAAA,GAAS,EAAE,GAAA,EAAK,EAAA,EAAI,OAAO,EAAA,EAAI,MAAA,EAAQ,EAAA,EAAI,IAAA,EAAM,EAAA,EAAG;AAAA,EACpD,UAAA;AAAA,EACA,QAAA;AAAA,EACA,gBAAA;AAAA,EACA,MAAA,GAAS,IAAA;AAAA,EACT,SAAA;AAAA,EACA,SAAA,GAAY,KAAA;AAAA,EACZ,SAAA;AAAA,EACA;AACF,CAAA,EACA,GAAA,EACA;AACA,EAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAe,WAAW,YAAA,EAAc,cAAA,KAAmB,aAAA,EAAc;AAC9F,EAAA,MAAM,YAAA,GAAqB,cAAQ,MAAM,uBAAA,CAAwB,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAClF,EAAA,MAAM,YAAA,GAAqB,cAAQ,MAAM,qBAAA,CAAsB,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEhF,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,uBAAO,GAAA,CAAC,wBAAqB,SAAA,EAAsB,CAAA;AAAA,EACrD;AAEA,EAAA,2BACG,cAAA,EAAA,EAAe,GAAA,EAAU,WAAsB,QAAA,EAAS,YAAA,EAAa,WACpE,QAAA,kBAAA,GAAA,CAAC,mBAAA,EAAA,EAAoB,KAAA,EAAM,MAAA,EAAO,QAAO,MAAA,EACvC,QAAA,kBAAA,IAAA,CAAC,aAAU,IAAA,EAAY,MAAA,EAAiB,GAAG,UAAA,EACzC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,UACE,QAAA,EAAA,QAAA,CAAS,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,0BACjB,gBAAA,EAAA,EAAyB,EAAA,EAAI,iBAAiB,GAAG,CAAA,CAAA,EAAI,IAAG,GAAA,EAAI,EAAA,EAAG,KAAI,EAAA,EAAG,GAAA,EAAI,IAAG,GAAA,EAC5E,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,MAAA,EAAO,IAAA,EAAK,SAAA,EAAW,WAAA,CAAY,IAAI,WAAA,CAAY,MAAM,CAAA,EAAG,WAAA,EAAa,WAAA,EAAa,CAAA;AAAA,sBAC5F,GAAA,CAAC,MAAA,EAAA,EAAK,MAAA,EAAO,MAAA,EAAO,SAAA,EAAW,WAAA,CAAY,CAAA,GAAI,WAAA,CAAY,MAAM,CAAA,EAAG,WAAA,EAAa,CAAA,EAAG;AAAA,KAAA,EAAA,EAFjE,GAGrB,CACD,CAAA,EACH,CAAA;AAAA,IAAA,CAEE,eAAe,WAAA,qBACf,GAAA;AAAA,MAAC,aAAA;AAAA,MAAA;AAAA,QACC,UAAA,EAAY,WAAA;AAAA,QACZ,QAAA,EAAU,WAAA;AAAA,QACV,QAAQ,SAAA,CAAU,MAAA;AAAA,QAClB,iBAAiB,SAAA,CAAU,eAAA;AAAA,QAC3B,eAAe,SAAA,CAAU;AAAA;AAAA,KAC3B;AAAA,IAGD,eAAe,IAAA,oBACd,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,OAAA,EAAS,QAAA;AAAA,QACT,IAAA,EAAM,aAAA;AAAA,QACN,QAAA,EAAU,KAAA;AAAA,QACV,QAAA,EAAU,KAAA;AAAA,QACV,UAAA,EAAY,EAAA;AAAA,QACZ,aAAA,EAAe,YAAA;AAAA,QACd,GAAG;AAAA;AAAA,KACN;AAAA,IAGD,aAAa,IAAA,oBACZ,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAA,EAAM,aAAA;AAAA,QACN,QAAA,EAAU,KAAA;AAAA,QACV,QAAA,EAAU,KAAA;AAAA,QACV,UAAA,EAAY,EAAA;AAAA,QACZ,aAAA,EAAe,YAAA;AAAA,QACd,GAAG;AAAA;AAAA,KACN;AAAA,oBAGF,GAAA;AAAA,MAAC,OAAA;AAAA,MAAA;AAAA,QACC,MAAA,EAAQ,cAAA;AAAA,QACR,yBAAS,GAAA,CAAC,YAAA,EAAA,EAAa,YAAA,EAA4B,SAAA,EAAW,kBAAkB,MAAA,EAAgB;AAAA;AAAA,KAClG;AAAA,IAEC,QAAA,CAAS,GAAA,CAAI,CAAC,GAAA,EAAK,CAAA,qBAClB,GAAA;AAAA,MAAC,IAAA;AAAA,MAAA;AAAA,QAEC,IAAA,EAAM,KAAA;AAAA,QACN,OAAA,EAAS,GAAA;AAAA,QACT,MAAA,EAAQ,WAAA,CAAY,CAAA,GAAI,WAAA,CAAY,MAAM,CAAA;AAAA,QAC1C,WAAA;AAAA,QACA,IAAA,EAAM,sBAAsB,GAAG,CAAA,CAAA,CAAA;AAAA,QAC/B,GAAA,EAAK,QAAA;AAAA,QACL,SAAA,EAAW,EAAE,CAAA,EAAG,CAAA,EAAG,aAAa,CAAA,EAAE;AAAA,QAClC,iBAAA,EAAmB,GAAA;AAAA,QACnB,eAAA,EAAgB;AAAA,OAAA;AAAA,MATX;AAAA,KAWR;AAAA,GAAA,EACH,GACF,CAAA,EACF,CAAA;AAEJ,CAAC;AACD,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"chunk-QJ7UB2ZQ.js","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport { AreaChart, Area, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'\n\nimport { useChartTheme } from '@/hooks/use-chart-theme'\nimport { type SupportedLocale } from '@/lib/utils'\nimport {\n ChartContainer,\n ChartLoadingSkeleton,\n ChartTooltip,\n localeAwareCategoryTick,\n localeAwareNumberTick,\n} from './chart-utils'\n\nexport interface PartoAreaChartProps {\n /** Row-oriented data: [{ name: \"فروردین\", series1: 50, series2: 30 }] */\n data: Array<Record<string, any>>\n /** Keys for each area series (e.g. ['فروش', 'سود']) */\n dataKeys: string[]\n /** Field name for X axis (default: 'name') */\n xAxisKey?: string\n /** Curve type */\n curve?: 'monotone' | 'linear' | 'natural' | 'step'\n /** Line width */\n strokeWidth?: number\n /** Area fill opacity */\n fillOpacity?: number\n /** Show dots on data points */\n showDots?: boolean\n /** Show horizontal grid lines */\n enableGridY?: boolean\n /** Show vertical grid lines */\n enableGridX?: boolean\n /** Chart margins */\n margin?: { top?: number; right?: number; bottom?: number; left?: number }\n /** Custom X axis config */\n axisBottom?: Record<string, any> | null\n /** Custom Y axis config */\n axisLeft?: Record<string, any> | null\n /** Custom tooltip formatter */\n tooltipFormatter?: (name: string, value: number) => React.ReactNode\n /**\n * Locale for digit formatting in tooltips and axis ticks. fa/ar render\n * Persian/Arabic digits with locale suffixes; en uses Latin K/M/B.\n * Default: 'fa'.\n */\n locale?: SupportedLocale\n className?: string\n isLoading?: boolean\n ariaLabel?: string\n /** Additional Recharts AreaChart props */\n chartProps?: Record<string, any>\n}\n\nexport const PartoAreaChart = React.forwardRef<HTMLDivElement, PartoAreaChartProps>(function PartoAreaChart(\n {\n data,\n dataKeys,\n xAxisKey = 'name',\n curve = 'monotone',\n strokeWidth = 2,\n fillOpacity = 0.08,\n showDots = false,\n enableGridY = true,\n enableGridX = false,\n margin = { top: 20, right: 20, bottom: 50, left: 50 },\n axisBottom,\n axisLeft,\n tooltipFormatter,\n locale = 'fa',\n className,\n isLoading = false,\n ariaLabel,\n chartProps,\n },\n ref\n) {\n const { chartColors, axisTickStyle, gridStyle, tooltipStyle, crosshairStyle } = useChartTheme()\n const defaultXTick = React.useMemo(() => localeAwareCategoryTick(locale), [locale])\n const defaultYTick = React.useMemo(() => localeAwareNumberTick(locale), [locale])\n\n if (isLoading) {\n return <ChartLoadingSkeleton className={className} />\n }\n\n return (\n <ChartContainer ref={ref} className={className} dataSlot=\"area-chart\" ariaLabel={ariaLabel}>\n <ResponsiveContainer width=\"100%\" height=\"100%\">\n <AreaChart data={data} margin={margin} {...chartProps}>\n <defs>\n {dataKeys.map((key, i) => (\n <linearGradient key={key} id={`area-gradient-${key}`} x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n <stop offset=\"0%\" stopColor={chartColors[i % chartColors.length]} stopOpacity={fillOpacity} />\n <stop offset=\"100%\" stopColor={chartColors[i % chartColors.length]} stopOpacity={0} />\n </linearGradient>\n ))}\n </defs>\n\n {(enableGridX || enableGridY) && (\n <CartesianGrid\n horizontal={enableGridY}\n vertical={enableGridX}\n stroke={gridStyle.stroke}\n strokeDasharray={gridStyle.strokeDasharray}\n strokeOpacity={gridStyle.strokeOpacity}\n />\n )}\n\n {axisBottom !== null && (\n <XAxis\n dataKey={xAxisKey}\n tick={axisTickStyle}\n tickLine={false}\n axisLine={false}\n tickMargin={12}\n tickFormatter={defaultXTick}\n {...axisBottom}\n />\n )}\n\n {axisLeft !== null && (\n <YAxis\n tick={axisTickStyle}\n tickLine={false}\n axisLine={false}\n tickMargin={12}\n tickFormatter={defaultYTick}\n {...axisLeft}\n />\n )}\n\n <Tooltip\n cursor={crosshairStyle}\n content={<ChartTooltip tooltipStyle={tooltipStyle} formatter={tooltipFormatter} locale={locale} />}\n />\n\n {dataKeys.map((key, i) => (\n <Area\n key={key}\n type={curve}\n dataKey={key}\n stroke={chartColors[i % chartColors.length]}\n strokeWidth={strokeWidth}\n fill={`url(#area-gradient-${key})`}\n dot={showDots}\n activeDot={{ r: 4, strokeWidth: 2 }}\n animationDuration={800}\n animationEasing=\"ease-out\"\n />\n ))}\n </AreaChart>\n </ResponsiveContainer>\n </ChartContainer>\n )\n})\nPartoAreaChart.displayName = 'PartoAreaChart'\n"]}
@@ -0,0 +1,269 @@
1
+ import { SIZE_VARIANTS_DEFAULT, SIZE_VARIANTS } from './chunk-AXAY64KL.js';
2
+ import { cn } from './chunk-4SVQNEVH.js';
3
+ import { Slot } from '@radix-ui/react-slot';
4
+ import { cva } from 'class-variance-authority';
5
+ import { Loader2 } from 'lucide-react';
6
+ import { forwardRef, cloneElement, isValidElement } from 'react';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+
9
+ var DESTRUCTIVE_VARIANT = `
10
+ text-foreground
11
+ bg-destructive-300 dark:bg-destructive-400 hover:bg-destructive-400 dark:hover:bg-destructive-600
12
+ border-destructive-500 hover:border-destructive
13
+ hover:text-hi-contrast
14
+ data-[state=open]:border-destructive
15
+ data-[state=open]:bg-destructive-400 dark:data-[state=open]:bg-destructive-600/80
16
+ `;
17
+ var buttonVariants = cva(
18
+ `inline-flex items-center justify-center
19
+ relative
20
+ cursor-pointer
21
+ gap-2
22
+ text-center
23
+ font-normal
24
+ ease-out
25
+ duration-200
26
+ rounded-md
27
+ outline-none
28
+ transition-all
29
+ active:scale-[0.98]
30
+ focus-visible:ring-2
31
+ focus-visible:ring-ring
32
+ focus-visible:ring-offset-2
33
+ border
34
+ disabled:pointer-events-none
35
+ disabled:opacity-50
36
+ [&_svg]:pointer-events-none
37
+ [&_svg]:shrink-0
38
+ `,
39
+ {
40
+ variants: {
41
+ variant: {
42
+ primary: `
43
+ bg-brand-400 dark:bg-brand-500
44
+ hover:bg-brand-300 dark:hover:bg-brand-600
45
+ text-foreground
46
+ border-brand-500/75 dark:border-brand/30
47
+ hover:border-brand-600 dark:hover:border-brand-500
48
+ data-[state=open]:bg-brand-400/80 dark:data-[state=open]:bg-brand-600/80
49
+ `,
50
+ default: `
51
+ text-foreground
52
+ bg-alternative dark:bg-muted hover:bg-selection
53
+ border-strong hover:border-stronger
54
+ data-[state=open]:bg-selection
55
+ data-[state=open]:border-button-hover
56
+ `,
57
+ secondary: `
58
+ bg-foreground
59
+ text-background hover:text-border-stronger
60
+ focus-visible:text-border-control
61
+ border-foreground-light hover:border-foreground-lighter
62
+ data-[state=open]:border-foreground-lighter
63
+ `,
64
+ outline: `
65
+ text-foreground
66
+ bg-transparent
67
+ border-strong hover:border-foreground-muted
68
+ data-[state=open]:border-stronger
69
+ `,
70
+ dashed: `
71
+ text-foreground
72
+ border
73
+ border-dashed
74
+ border-strong hover:border-stronger
75
+ bg-transparent
76
+ data-[state=open]:border-stronger
77
+ `,
78
+ link: `
79
+ text-brand-600
80
+ border
81
+ border-transparent
82
+ hover:bg-brand-400
83
+ border-opacity-0
84
+ bg-opacity-0
85
+ shadow-none
86
+ data-[state=open]:bg-brand-400
87
+ `,
88
+ text: `
89
+ text-foreground
90
+ hover:bg-surface-300
91
+ shadow-none
92
+ data-[state=open]:bg-surface-300
93
+ border-transparent
94
+ `,
95
+ danger: DESTRUCTIVE_VARIANT,
96
+ warning: `
97
+ text-foreground
98
+ bg-warning-300 dark:bg-warning-400 hover:bg-warning-400 dark:hover:bg-warning-600
99
+ border-warning-500 hover:border-warning
100
+ hover:text-hi-contrast
101
+ data-[state=open]:border-warning
102
+ data-[state=open]:bg-warning-400 dark:data-[state=open]:bg-warning-600/80
103
+ `,
104
+ destructive: DESTRUCTIVE_VARIANT,
105
+ ghost: `
106
+ text-foreground
107
+ hover:bg-surface-100 dark:hover:bg-surface-200
108
+ border-transparent
109
+ `
110
+ },
111
+ block: {
112
+ true: "w-full flex items-center justify-center"
113
+ },
114
+ size: {
115
+ ...SIZE_VARIANTS,
116
+ default: SIZE_VARIANTS.sm,
117
+ icon: "size-9"
118
+ },
119
+ disabled: {
120
+ true: "opacity-50 cursor-not-allowed pointer-events-none"
121
+ },
122
+ rounded: {
123
+ true: "rounded-full"
124
+ }
125
+ },
126
+ defaultVariants: {
127
+ variant: "default",
128
+ size: SIZE_VARIANTS_DEFAULT
129
+ }
130
+ }
131
+ );
132
+ var IconContainerVariants = cva("inline-flex items-center justify-center", {
133
+ variants: {
134
+ size: {
135
+ xs: "[&_svg]:size-[14px]",
136
+ sm: "[&_svg]:size-[18px]",
137
+ md: "[&_svg]:size-[20px]",
138
+ lg: "[&_svg]:size-[20px]",
139
+ xl: "[&_svg]:size-[24px]",
140
+ /** @deprecated */
141
+ tiny: "[&_svg]:size-[14px]",
142
+ /** @deprecated */
143
+ small: "[&_svg]:size-[18px]",
144
+ /** @deprecated */
145
+ medium: "[&_svg]:size-[20px]",
146
+ /** @deprecated */
147
+ large: "[&_svg]:size-[20px]",
148
+ /** @deprecated */
149
+ xlarge: "[&_svg]:size-[24px]",
150
+ default: "[&_svg]:size-[18px]",
151
+ icon: "[&_svg]:size-[18px]"
152
+ },
153
+ variant: {
154
+ primary: "text-brand-600",
155
+ default: "text-foreground-lighter",
156
+ secondary: "text-border-muted",
157
+ outline: "text-foreground-lighter",
158
+ dashed: "text-foreground-lighter",
159
+ link: "text-brand-600",
160
+ text: "text-foreground-lighter",
161
+ danger: "text-destructive-600",
162
+ warning: "text-warning",
163
+ destructive: "text-destructive-600",
164
+ ghost: "text-foreground-lighter"
165
+ }
166
+ }
167
+ });
168
+ var loadingVariants = cva("", {
169
+ variants: {
170
+ variant: {
171
+ primary: "text-brand-600",
172
+ default: "text-foreground-lighter",
173
+ secondary: "text-border-muted",
174
+ outline: "text-foreground-lighter",
175
+ dashed: "text-foreground-lighter",
176
+ link: "text-brand-600",
177
+ text: "text-foreground-muted",
178
+ danger: "text-destructive-600",
179
+ warning: "text-warning",
180
+ destructive: "text-destructive-600",
181
+ ghost: "text-foreground-lighter"
182
+ },
183
+ loading: {
184
+ default: "",
185
+ true: `animate-spin`
186
+ }
187
+ }
188
+ });
189
+ var Button = forwardRef(
190
+ ({
191
+ asChild = false,
192
+ variant,
193
+ type,
194
+ size = SIZE_VARIANTS_DEFAULT,
195
+ children,
196
+ isLoading,
197
+ loading,
198
+ block,
199
+ icon,
200
+ iconEnd,
201
+ iconStart,
202
+ iconRight,
203
+ iconLeft,
204
+ htmlType = "button",
205
+ rounded,
206
+ className,
207
+ ...props
208
+ }, ref) => {
209
+ if (process.env.NODE_ENV !== "production") {
210
+ const deprecatedSizes = ["tiny", "small", "medium", "large", "xlarge"];
211
+ if (size && deprecatedSizes.includes(size)) {
212
+ console.warn(`[Parto UI] Button: size="${size}" is deprecated. Use xs|sm|md|lg|xl instead.`);
213
+ }
214
+ }
215
+ const Comp = asChild ? Slot : "button";
216
+ const { tabIndex } = props;
217
+ const buttonVariant = type && typeof type === "string" && !["button", "submit", "reset"].includes(type) ? type : variant || "default";
218
+ const _loading = isLoading ?? loading;
219
+ const resolvedIconStart = icon ?? iconStart ?? iconLeft;
220
+ const resolvedIconEnd = iconEnd ?? iconRight;
221
+ const showIcon = _loading || resolvedIconStart;
222
+ const disabled = _loading === true || props.disabled;
223
+ const computedTabIndex = tabIndex !== void 0 ? tabIndex : disabled ? -1 : 0;
224
+ const iconSize = size === "default" ? "sm" : size === "icon" ? "sm" : size ?? "sm";
225
+ return /* @__PURE__ */ jsx(
226
+ Comp,
227
+ {
228
+ ref,
229
+ "data-slot": "button",
230
+ "data-size": size,
231
+ type: htmlType,
232
+ disabled,
233
+ "aria-busy": _loading || void 0,
234
+ tabIndex: computedTabIndex,
235
+ className: cn(buttonVariants({ variant: buttonVariant, size, disabled, block, rounded }), className),
236
+ onClick: (e) => {
237
+ if (disabled) return e.preventDefault();
238
+ else props?.onClick?.(e);
239
+ },
240
+ ...props,
241
+ children: asChild ? isValidElement(children) ? cloneElement(
242
+ children,
243
+ void 0,
244
+ showIcon && (_loading ? /* @__PURE__ */ jsx("div", { className: cn(IconContainerVariants({ size: iconSize, variant: buttonVariant })), children: /* @__PURE__ */ jsx(Loader2, { className: cn(loadingVariants({ loading: _loading, variant: buttonVariant })) }) }) : resolvedIconStart ? /* @__PURE__ */ jsx("div", { className: cn(IconContainerVariants({ size: iconSize, variant: buttonVariant })), children: resolvedIconStart }) : null),
245
+ children.props?.children && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-2 truncate", children: children.props.children }),
246
+ resolvedIconEnd && !_loading && /* @__PURE__ */ jsx("div", { className: cn(IconContainerVariants({ size: iconSize, variant: buttonVariant })), children: resolvedIconEnd })
247
+ ) : null : /* @__PURE__ */ jsxs(Fragment, { children: [
248
+ showIcon && (_loading ? /* @__PURE__ */ jsxs("div", { className: cn(IconContainerVariants({ size: iconSize, variant: buttonVariant })), children: [
249
+ /* @__PURE__ */ jsx(
250
+ Loader2,
251
+ {
252
+ "aria-hidden": "true",
253
+ className: cn(loadingVariants({ loading: _loading, variant: buttonVariant }))
254
+ }
255
+ ),
256
+ /* @__PURE__ */ jsx("span", { className: "sr-only", children: "\u062F\u0631 \u062D\u0627\u0644 \u0628\u0627\u0631\u06AF\u0630\u0627\u0631\u06CC..." })
257
+ ] }) : resolvedIconStart ? /* @__PURE__ */ jsx("div", { className: cn(IconContainerVariants({ size: iconSize, variant: buttonVariant })), children: resolvedIconStart }) : null),
258
+ children && /* @__PURE__ */ jsx("span", { className: "inline-flex items-center gap-2 truncate", children }),
259
+ resolvedIconEnd && !_loading && /* @__PURE__ */ jsx("div", { className: cn(IconContainerVariants({ size: iconSize, variant: buttonVariant })), children: resolvedIconEnd })
260
+ ] })
261
+ }
262
+ );
263
+ }
264
+ );
265
+ Button.displayName = "Button";
266
+
267
+ export { Button, buttonVariants };
268
+ //# sourceMappingURL=chunk-RA5KZNG5.js.map
269
+ //# sourceMappingURL=chunk-RA5KZNG5.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/button.tsx"],"names":[],"mappings":"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","file":"chunk-RA5KZNG5.js","sourcesContent":["'use client'\n\nimport { Slot } from '@radix-ui/react-slot'\nimport { VariantProps, cva } from 'class-variance-authority'\nimport { Loader2 } from 'lucide-react'\nimport { cloneElement, forwardRef, isValidElement } from 'react'\nimport { SIZE_VARIANTS, SIZE_VARIANTS_DEFAULT, type SizeWithLegacy } from '@/lib/constants'\nimport { cn } from '@/lib/utils'\n\nexport type ButtonVariantProps = VariantProps<typeof buttonVariants>\n\nconst DESTRUCTIVE_VARIANT = `\n text-foreground\n bg-destructive-300 dark:bg-destructive-400 hover:bg-destructive-400 dark:hover:bg-destructive-600\n border-destructive-500 hover:border-destructive\n hover:text-hi-contrast\n data-[state=open]:border-destructive\n data-[state=open]:bg-destructive-400 dark:data-[state=open]:bg-destructive-600/80\n`\n\nconst buttonVariants = cva(\n `inline-flex items-center justify-center\n relative\n cursor-pointer\n gap-2\n text-center\n font-normal\n ease-out\n duration-200\n rounded-md\n outline-none\n transition-all\n active:scale-[0.98]\n focus-visible:ring-2\n focus-visible:ring-ring\n focus-visible:ring-offset-2\n border\n disabled:pointer-events-none\n disabled:opacity-50\n [&_svg]:pointer-events-none\n [&_svg]:shrink-0\n `,\n {\n variants: {\n variant: {\n primary: `\n bg-brand-400 dark:bg-brand-500\n hover:bg-brand-300 dark:hover:bg-brand-600\n text-foreground\n border-brand-500/75 dark:border-brand/30\n hover:border-brand-600 dark:hover:border-brand-500\n data-[state=open]:bg-brand-400/80 dark:data-[state=open]:bg-brand-600/80\n `,\n default: `\n text-foreground\n bg-alternative dark:bg-muted hover:bg-selection\n border-strong hover:border-stronger\n data-[state=open]:bg-selection\n data-[state=open]:border-button-hover\n `,\n secondary: `\n bg-foreground\n text-background hover:text-border-stronger\n focus-visible:text-border-control\n border-foreground-light hover:border-foreground-lighter\n data-[state=open]:border-foreground-lighter\n `,\n outline: `\n text-foreground\n bg-transparent\n border-strong hover:border-foreground-muted\n data-[state=open]:border-stronger\n `,\n dashed: `\n text-foreground\n border\n border-dashed\n border-strong hover:border-stronger\n bg-transparent\n data-[state=open]:border-stronger\n `,\n link: `\n text-brand-600\n border\n border-transparent\n hover:bg-brand-400\n border-opacity-0\n bg-opacity-0\n shadow-none\n data-[state=open]:bg-brand-400\n `,\n text: `\n text-foreground\n hover:bg-surface-300\n shadow-none\n data-[state=open]:bg-surface-300\n border-transparent\n `,\n danger: DESTRUCTIVE_VARIANT,\n warning: `\n text-foreground\n bg-warning-300 dark:bg-warning-400 hover:bg-warning-400 dark:hover:bg-warning-600\n border-warning-500 hover:border-warning\n hover:text-hi-contrast\n data-[state=open]:border-warning\n data-[state=open]:bg-warning-400 dark:data-[state=open]:bg-warning-600/80\n `,\n destructive: DESTRUCTIVE_VARIANT,\n ghost: `\n text-foreground\n hover:bg-surface-100 dark:hover:bg-surface-200\n border-transparent\n `,\n },\n block: {\n true: 'w-full flex items-center justify-center',\n },\n size: {\n ...SIZE_VARIANTS,\n default: SIZE_VARIANTS.sm,\n icon: 'size-9',\n },\n disabled: {\n true: 'opacity-50 cursor-not-allowed pointer-events-none',\n },\n rounded: {\n true: 'rounded-full',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: SIZE_VARIANTS_DEFAULT,\n },\n }\n)\n\nconst IconContainerVariants = cva('inline-flex items-center justify-center', {\n variants: {\n size: {\n xs: '[&_svg]:size-[14px]',\n sm: '[&_svg]:size-[18px]',\n md: '[&_svg]:size-[20px]',\n lg: '[&_svg]:size-[20px]',\n xl: '[&_svg]:size-[24px]',\n /** @deprecated */ tiny: '[&_svg]:size-[14px]',\n /** @deprecated */ small: '[&_svg]:size-[18px]',\n /** @deprecated */ medium: '[&_svg]:size-[20px]',\n /** @deprecated */ large: '[&_svg]:size-[20px]',\n /** @deprecated */ xlarge: '[&_svg]:size-[24px]',\n default: '[&_svg]:size-[18px]',\n icon: '[&_svg]:size-[18px]',\n },\n variant: {\n primary: 'text-brand-600',\n default: 'text-foreground-lighter',\n secondary: 'text-border-muted',\n outline: 'text-foreground-lighter',\n dashed: 'text-foreground-lighter',\n link: 'text-brand-600',\n text: 'text-foreground-lighter',\n danger: 'text-destructive-600',\n warning: 'text-warning',\n destructive: 'text-destructive-600',\n ghost: 'text-foreground-lighter',\n },\n },\n})\n\nexport type LoadingVariantProps = VariantProps<typeof loadingVariants>\nconst loadingVariants = cva('', {\n variants: {\n variant: {\n primary: 'text-brand-600',\n default: 'text-foreground-lighter',\n secondary: 'text-border-muted',\n outline: 'text-foreground-lighter',\n dashed: 'text-foreground-lighter',\n link: 'text-brand-600',\n text: 'text-foreground-muted',\n danger: 'text-destructive-600',\n warning: 'text-warning',\n destructive: 'text-destructive-600',\n ghost: 'text-foreground-lighter',\n },\n loading: {\n default: '',\n true: `animate-spin`,\n },\n },\n})\n\nexport interface ButtonProps\n extends\n Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'type'>,\n Omit<ButtonVariantProps, 'disabled'>,\n Omit<LoadingVariantProps, 'variant'> {\n asChild?: boolean\n type?: ButtonVariantProps['variant'] | React.ButtonHTMLAttributes<HTMLButtonElement>['type']\n htmlType?: React.ButtonHTMLAttributes<HTMLButtonElement>['type']\n icon?: React.ReactNode\n iconStart?: React.ReactNode\n iconEnd?: React.ReactNode\n /** @deprecated Use iconStart instead */\n iconLeft?: React.ReactNode\n /** @deprecated Use iconEnd instead */\n iconRight?: React.ReactNode\n isLoading?: boolean\n /** @deprecated Use `isLoading` instead */\n loading?: boolean\n block?: boolean\n rounded?: boolean\n}\n\nconst Button = forwardRef<HTMLButtonElement, ButtonProps>(\n (\n {\n asChild = false,\n variant,\n type,\n size = SIZE_VARIANTS_DEFAULT,\n children,\n isLoading,\n loading,\n block,\n icon,\n iconEnd,\n iconStart,\n iconRight,\n iconLeft,\n htmlType = 'button',\n rounded,\n className,\n ...props\n },\n ref\n ) => {\n if (process.env.NODE_ENV !== 'production') {\n const deprecatedSizes = ['tiny', 'small', 'medium', 'large', 'xlarge']\n if (size && deprecatedSizes.includes(size as string)) {\n console.warn(`[Parto UI] Button: size=\"${size}\" is deprecated. Use xs|sm|md|lg|xl instead.`)\n }\n }\n\n const Comp = asChild ? Slot : 'button'\n const { tabIndex } = props\n\n // Support both 'type' (Supabase style) and 'variant' (shadcn style)\n // If type is provided and it's not a button HTML type, use it as variant\n const buttonVariant =\n type && typeof type === 'string' && !['button', 'submit', 'reset'].includes(type)\n ? (type as ButtonVariantProps['variant'])\n : variant || 'default'\n\n const _loading = isLoading ?? loading\n // Support deprecated iconLeft/iconRight alongside new iconStart/iconEnd\n const resolvedIconStart = icon ?? iconStart ?? iconLeft\n const resolvedIconEnd = iconEnd ?? iconRight\n const showIcon = _loading || resolvedIconStart\n const disabled = _loading === true || props.disabled\n\n // Set default tabIndex for proper Safari focus handling\n // - Explicit tabIndex prop takes precedence\n // - If disabled, default to -1 (unless explicitly set)\n // - Otherwise, default to 0 for keyboard accessibility\n const computedTabIndex = tabIndex !== undefined ? tabIndex : disabled ? -1 : 0\n\n // Normalize size for IconContainerVariants\n const iconSize: SizeWithLegacy | 'default' | 'icon' =\n size === 'default' ? 'sm' : size === 'icon' ? 'sm' : (size ?? 'sm')\n\n return (\n <Comp\n ref={ref}\n data-slot=\"button\"\n data-size={size}\n type={htmlType}\n disabled={disabled}\n aria-busy={_loading || undefined}\n tabIndex={computedTabIndex}\n className={cn(buttonVariants({ variant: buttonVariant, size, disabled, block, rounded }), className)}\n onClick={(e) => {\n // Prevents redirecting if Button is used with a link-based child element\n if (disabled) return e.preventDefault()\n else props?.onClick?.(e)\n }}\n {...props}\n >\n {asChild ? (\n isValidElement(children) ? (\n cloneElement(\n children,\n undefined,\n showIcon &&\n (_loading ? (\n <div className={cn(IconContainerVariants({ size: iconSize, variant: buttonVariant }))}>\n <Loader2 className={cn(loadingVariants({ loading: _loading, variant: buttonVariant }))} />\n </div>\n ) : resolvedIconStart ? (\n <div className={cn(IconContainerVariants({ size: iconSize, variant: buttonVariant }))}>\n {resolvedIconStart}\n </div>\n ) : null),\n (children.props as { children?: React.ReactNode })?.children && (\n <span className=\"inline-flex items-center gap-2 truncate\">\n {(children.props as { children?: React.ReactNode }).children}\n </span>\n ),\n resolvedIconEnd && !_loading && (\n <div className={cn(IconContainerVariants({ size: iconSize, variant: buttonVariant }))}>\n {resolvedIconEnd}\n </div>\n )\n )\n ) : null\n ) : (\n <>\n {showIcon &&\n (_loading ? (\n <div className={cn(IconContainerVariants({ size: iconSize, variant: buttonVariant }))}>\n <Loader2\n aria-hidden=\"true\"\n className={cn(loadingVariants({ loading: _loading, variant: buttonVariant }))}\n />\n <span className=\"sr-only\">در حال بارگذاری...</span>\n </div>\n ) : resolvedIconStart ? (\n <div className={cn(IconContainerVariants({ size: iconSize, variant: buttonVariant }))}>\n {resolvedIconStart}\n </div>\n ) : null)}\n {children && <span className=\"inline-flex items-center gap-2 truncate\">{children}</span>}\n {resolvedIconEnd && !_loading && (\n <div className={cn(IconContainerVariants({ size: iconSize, variant: buttonVariant }))}>\n {resolvedIconEnd}\n </div>\n )}\n </>\n )}\n </Comp>\n )\n }\n)\n\nButton.displayName = 'Button'\n\nexport { Button, buttonVariants }\n"]}
@@ -0,0 +1,44 @@
1
+ import { cn } from './chunk-4SVQNEVH.js';
2
+ import * as AvatarPrimitive from '@radix-ui/react-avatar';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ function Avatar({ className, ...props }) {
6
+ return /* @__PURE__ */ jsx(
7
+ AvatarPrimitive.Root,
8
+ {
9
+ "data-slot": "avatar",
10
+ className: cn(
11
+ "relative inline-flex size-8 shrink-0 overflow-hidden rounded-full align-middle text-[0px] leading-none",
12
+ className
13
+ ),
14
+ ...props
15
+ }
16
+ );
17
+ }
18
+ function AvatarImage({ className, ...props }) {
19
+ return /* @__PURE__ */ jsx(
20
+ AvatarPrimitive.Image,
21
+ {
22
+ "data-slot": "avatar-image",
23
+ className: cn("block size-full object-cover object-center", className),
24
+ ...props
25
+ }
26
+ );
27
+ }
28
+ function AvatarFallback({ className, ...props }) {
29
+ return /* @__PURE__ */ jsx(
30
+ AvatarPrimitive.Fallback,
31
+ {
32
+ "data-slot": "avatar-fallback",
33
+ className: cn("bg-muted flex size-full items-center justify-center rounded-full text-sm", className),
34
+ ...props
35
+ }
36
+ );
37
+ }
38
+ Avatar.displayName = "Avatar";
39
+ AvatarImage.displayName = "AvatarImage";
40
+ AvatarFallback.displayName = "AvatarFallback";
41
+
42
+ export { Avatar, AvatarFallback, AvatarImage };
43
+ //# sourceMappingURL=chunk-RJ3HYZ7S.js.map
44
+ //# sourceMappingURL=chunk-RJ3HYZ7S.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/ui/avatar.tsx"],"names":[],"mappings":";;;;AAOA,SAAS,MAAA,CAAO,EAAE,SAAA,EAAW,GAAG,OAAM,EAAsD;AAC1F,EAAA,uBACE,GAAA;AAAA,IAAiB,eAAA,CAAA,IAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,QAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,wGAAA;AAAA,QACA;AAAA,OACF;AAAA,MACC,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,WAAA,CAAY,EAAE,SAAA,EAAW,GAAG,OAAM,EAAuD;AAChG,EAAA,uBACE,GAAA;AAAA,IAAiB,eAAA,CAAA,KAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,4CAAA,EAA8C,SAAS,CAAA;AAAA,MACpE,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,SAAS,cAAA,CAAe,EAAE,SAAA,EAAW,GAAG,OAAM,EAA0D;AACtG,EAAA,uBACE,GAAA;AAAA,IAAiB,eAAA,CAAA,QAAA;AAAA,IAAhB;AAAA,MACC,WAAA,EAAU,iBAAA;AAAA,MACV,SAAA,EAAW,EAAA,CAAG,0EAAA,EAA4E,SAAS,CAAA;AAAA,MAClG,GAAG;AAAA;AAAA,GACN;AAEJ;AAEA,MAAA,CAAO,WAAA,GAAc,QAAA;AACrB,WAAA,CAAY,WAAA,GAAc,aAAA;AAC1B,cAAA,CAAe,WAAA,GAAc,gBAAA","file":"chunk-RJ3HYZ7S.js","sourcesContent":["'use client'\n\nimport * as React from 'react'\nimport * as AvatarPrimitive from '@radix-ui/react-avatar'\n\nimport { cn } from '@/lib/utils'\n\nfunction Avatar({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Root>) {\n return (\n <AvatarPrimitive.Root\n data-slot=\"avatar\"\n className={cn(\n 'relative inline-flex size-8 shrink-0 overflow-hidden rounded-full align-middle text-[0px] leading-none',\n className\n )}\n {...props}\n />\n )\n}\n\nfunction AvatarImage({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Image>) {\n return (\n <AvatarPrimitive.Image\n data-slot=\"avatar-image\"\n className={cn('block size-full object-cover object-center', className)}\n {...props}\n />\n )\n}\n\nfunction AvatarFallback({ className, ...props }: React.ComponentProps<typeof AvatarPrimitive.Fallback>) {\n return (\n <AvatarPrimitive.Fallback\n data-slot=\"avatar-fallback\"\n className={cn('bg-muted flex size-full items-center justify-center rounded-full text-sm', className)}\n {...props}\n />\n )\n}\n\nAvatar.displayName = 'Avatar'\nAvatarImage.displayName = 'AvatarImage'\nAvatarFallback.displayName = 'AvatarFallback'\n\nexport { Avatar, AvatarImage, AvatarFallback }\n"]}
@@ -0,0 +1,128 @@
1
+ import * as React from 'react';
2
+
3
+ // src/hooks/use-hotkeys.ts
4
+ function isMac() {
5
+ if (typeof navigator === "undefined") return false;
6
+ const ua = navigator.userAgentData?.platform;
7
+ const platform = ua ?? navigator.platform ?? "";
8
+ return /mac|darwin/i.test(platform);
9
+ }
10
+ var SPECIAL_KEY_MAP = {
11
+ " ": "space",
12
+ spacebar: "space",
13
+ esc: "escape",
14
+ del: "delete",
15
+ return: "enter",
16
+ arrowup: "up",
17
+ arrowdown: "down",
18
+ arrowleft: "left",
19
+ arrowright: "right"
20
+ };
21
+ function normalizeKey(raw) {
22
+ const lower = raw.toLowerCase();
23
+ return SPECIAL_KEY_MAP[lower] ?? lower;
24
+ }
25
+ function parseCombo(combo) {
26
+ const parts = combo.toLowerCase().split("+").map((s) => s.trim()).filter(Boolean);
27
+ const result = {
28
+ mod: false,
29
+ ctrl: false,
30
+ cmd: false,
31
+ shift: false,
32
+ alt: false,
33
+ meta: false,
34
+ key: ""
35
+ };
36
+ for (const p of parts) {
37
+ if (p === "mod") result.mod = true;
38
+ else if (p === "ctrl" || p === "control") result.ctrl = true;
39
+ else if (p === "cmd" || p === "command" || p === "win") result.cmd = true;
40
+ else if (p === "shift") result.shift = true;
41
+ else if (p === "alt" || p === "option" || p === "opt") result.alt = true;
42
+ else if (p === "meta") result.meta = true;
43
+ else result.key = normalizeKey(p);
44
+ }
45
+ return result;
46
+ }
47
+ function matches(parsed, event, mac) {
48
+ const requiredCmd = parsed.cmd || parsed.mod && mac;
49
+ const requiredCtrl = parsed.ctrl || parsed.mod && !mac;
50
+ if (requiredCmd !== event.metaKey) return false;
51
+ if (requiredCtrl !== event.ctrlKey) return false;
52
+ if (parsed.shift !== event.shiftKey) return false;
53
+ if (parsed.alt !== event.altKey) return false;
54
+ if (parsed.meta && !mac && !event.metaKey) return false;
55
+ if (!parsed.key) return true;
56
+ const eventKey = normalizeKey(event.key);
57
+ return eventKey === parsed.key;
58
+ }
59
+ function isEditable(el) {
60
+ if (!(el instanceof HTMLElement)) return false;
61
+ if (el.isContentEditable) return true;
62
+ const tag = el.tagName;
63
+ if (tag === "INPUT") {
64
+ const type = el.type;
65
+ return !["button", "submit", "reset", "checkbox", "radio", "range", "color", "file"].includes(type);
66
+ }
67
+ return tag === "TEXTAREA" || tag === "SELECT";
68
+ }
69
+ function hasModifier(event) {
70
+ return event.metaKey || event.ctrlKey || event.altKey;
71
+ }
72
+ function resolveTarget(target) {
73
+ if (!target) return typeof document !== "undefined" ? document : null;
74
+ if (target instanceof Document) return target;
75
+ if ("current" in target) return target.current ?? null;
76
+ return target;
77
+ }
78
+ function useHotkeys(combo, handler, options = {}) {
79
+ const { preventDefault = true, ignoreWhenTyping = true, enabled = true, target } = options;
80
+ const handlerRef = React.useRef(handler);
81
+ React.useEffect(() => {
82
+ handlerRef.current = handler;
83
+ }, [handler]);
84
+ React.useEffect(() => {
85
+ if (!enabled) return;
86
+ const resolvedTarget = resolveTarget(target);
87
+ if (!resolvedTarget) return;
88
+ const combos = (Array.isArray(combo) ? combo : [combo]).map(parseCombo);
89
+ const mac = isMac();
90
+ const listener = (event) => {
91
+ const keyboardEvent = event;
92
+ const matched = combos.find((parsed) => matches(parsed, keyboardEvent, mac));
93
+ if (!matched) return;
94
+ if (ignoreWhenTyping && isEditable(keyboardEvent.target) && !hasModifier(keyboardEvent)) {
95
+ return;
96
+ }
97
+ if (preventDefault) keyboardEvent.preventDefault();
98
+ handlerRef.current(keyboardEvent);
99
+ };
100
+ resolvedTarget.addEventListener("keydown", listener);
101
+ return () => {
102
+ resolvedTarget.removeEventListener("keydown", listener);
103
+ };
104
+ }, [Array.isArray(combo) ? combo.join("|") : combo, enabled, ignoreWhenTyping, preventDefault, target]);
105
+ }
106
+ function formatHotkey(combo) {
107
+ const mac = isMac();
108
+ return combo.split("+").map((p) => {
109
+ const t = p.trim().toLowerCase();
110
+ if (t === "mod") return mac ? "\u2318" : "Ctrl";
111
+ if (t === "cmd" || t === "meta") return mac ? "\u2318" : "Win";
112
+ if (t === "ctrl" || t === "control") return mac ? "\u2303" : "Ctrl";
113
+ if (t === "shift") return mac ? "\u21E7" : "Shift";
114
+ if (t === "alt" || t === "option" || t === "opt") return mac ? "\u2325" : "Alt";
115
+ if (t === "enter" || t === "return") return "\u21B5";
116
+ if (t === "escape" || t === "esc") return "Esc";
117
+ if (t === "space") return "Space";
118
+ if (t === "up") return "\u2191";
119
+ if (t === "down") return "\u2193";
120
+ if (t === "left") return "\u2190";
121
+ if (t === "right") return "\u2192";
122
+ return t.length === 1 ? t.toUpperCase() : t;
123
+ }).join(mac ? "" : "+");
124
+ }
125
+
126
+ export { formatHotkey, useHotkeys };
127
+ //# sourceMappingURL=chunk-RZNRIOLT.js.map
128
+ //# sourceMappingURL=chunk-RZNRIOLT.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/hooks/use-hotkeys.ts"],"names":[],"mappings":"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","file":"chunk-RZNRIOLT.js","sourcesContent":["'use client'\n\nimport * as React from 'react'\n\n/**\n * Hotkey string grammar:\n *\n * <part>[+<part>]*\n *\n * where each <part> is one of:\n * mod — Cmd on macOS, Ctrl on everything else (recommended)\n * ctrl / cmd — explicit, cross-platform tokens\n * shift | alt | meta\n * <single key> — lowercase character, 'space', 'enter', 'escape', 'tab',\n * arrow{up,down,left,right}, 'slash', 'backspace', etc.\n *\n * Examples:\n * 'mod+k' — ⌘K on macOS, CtrlK elsewhere\n * 'mod+shift+p'\n * 'escape'\n * 'ctrl+k' — explicit Ctrl (no Cmd fallback on macOS)\n *\n * Passing an array of strings is treated as an OR — any combo fires the handler.\n */\nexport type HotkeyCombo = string | readonly string[]\n\nexport interface UseHotkeysOptions {\n /**\n * When true, `event.preventDefault()` is called on matched combos.\n * Default: true. Useful to allow the browser's native 'mod+k' (address bar)\n * to keep working — set to false if the handler only does something conditionally.\n */\n preventDefault?: boolean\n /**\n * Skip the handler when focus is inside an editable control (input, textarea,\n * contenteditable). The exception: combos that include a modifier (mod/ctrl/\n * cmd/alt) still fire — they are unambiguous shortcuts, not typing.\n * Default: true.\n */\n ignoreWhenTyping?: boolean\n /**\n * When false, the hook unregisters its listener. Useful for conditionally\n * enabling shortcuts (e.g., only while a panel is open).\n * Default: true.\n */\n enabled?: boolean\n /**\n * DOM target. Defaults to `document`. Pass a ref for scoped shortcuts (e.g.,\n * only when a specific panel has focus within).\n */\n target?: React.RefObject<HTMLElement | null> | HTMLElement | Document | null\n}\n\nfunction isMac(): boolean {\n if (typeof navigator === 'undefined') return false\n // `userAgentData.platform` is the modern API; fall back to platform string.\n // Accept 'darwin' (nodejs tests) and 'MacIntel'/'Mac OS X'.\n const ua = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData?.platform\n const platform = ua ?? navigator.platform ?? ''\n return /mac|darwin/i.test(platform)\n}\n\nconst SPECIAL_KEY_MAP: Record<string, string> = {\n ' ': 'space',\n spacebar: 'space',\n esc: 'escape',\n del: 'delete',\n return: 'enter',\n arrowup: 'up',\n arrowdown: 'down',\n arrowleft: 'left',\n arrowright: 'right',\n}\n\nfunction normalizeKey(raw: string): string {\n const lower = raw.toLowerCase()\n return SPECIAL_KEY_MAP[lower] ?? lower\n}\n\ntype ParsedCombo = {\n mod: boolean\n ctrl: boolean\n cmd: boolean\n shift: boolean\n alt: boolean\n meta: boolean\n key: string\n}\n\nfunction parseCombo(combo: string): ParsedCombo {\n const parts = combo\n .toLowerCase()\n .split('+')\n .map((s) => s.trim())\n .filter(Boolean)\n const result: ParsedCombo = {\n mod: false,\n ctrl: false,\n cmd: false,\n shift: false,\n alt: false,\n meta: false,\n key: '',\n }\n for (const p of parts) {\n if (p === 'mod') result.mod = true\n else if (p === 'ctrl' || p === 'control') result.ctrl = true\n else if (p === 'cmd' || p === 'command' || p === 'win') result.cmd = true\n else if (p === 'shift') result.shift = true\n else if (p === 'alt' || p === 'option' || p === 'opt') result.alt = true\n else if (p === 'meta') result.meta = true\n else result.key = normalizeKey(p)\n }\n return result\n}\n\nfunction matches(parsed: ParsedCombo, event: KeyboardEvent, mac: boolean): boolean {\n // `mod` resolves to Cmd on macOS, Ctrl elsewhere. Track both sides of the combo.\n const requiredCmd = parsed.cmd || (parsed.mod && mac)\n const requiredCtrl = parsed.ctrl || (parsed.mod && !mac)\n\n if (requiredCmd !== event.metaKey) return false\n if (requiredCtrl !== event.ctrlKey) return false\n if (parsed.shift !== event.shiftKey) return false\n if (parsed.alt !== event.altKey) return false\n // `meta` (plain) aliases Cmd on macOS — avoid double-matching when both mod+meta are specified.\n if (parsed.meta && !mac && !event.metaKey) return false\n\n if (!parsed.key) return true\n const eventKey = normalizeKey(event.key)\n return eventKey === parsed.key\n}\n\nfunction isEditable(el: EventTarget | null): boolean {\n if (!(el instanceof HTMLElement)) return false\n if (el.isContentEditable) return true\n const tag = el.tagName\n if (tag === 'INPUT') {\n const type = (el as HTMLInputElement).type\n // Buttons and checkboxes aren't \"typing\" — don't block.\n return !['button', 'submit', 'reset', 'checkbox', 'radio', 'range', 'color', 'file'].includes(type)\n }\n return tag === 'TEXTAREA' || tag === 'SELECT'\n}\n\nfunction hasModifier(event: KeyboardEvent): boolean {\n return event.metaKey || event.ctrlKey || event.altKey\n}\n\nfunction resolveTarget(target: UseHotkeysOptions['target']): EventTarget | null {\n if (!target) return typeof document !== 'undefined' ? document : null\n if (target instanceof Document) return target\n if ('current' in target) return target.current ?? null\n return target\n}\n\n/**\n * Register a keyboard shortcut. Handler fires when the combo matches, respecting\n * `ignoreWhenTyping` (default true) — except when a modifier is part of the combo,\n * which always wins. Returns nothing; cleanup is automatic.\n *\n * @example\n * useHotkeys('mod+k', () => setOpen((v) => !v))\n * useHotkeys(['escape', 'mod+w'], close, { enabled: open })\n */\nexport function useHotkeys(\n combo: HotkeyCombo,\n handler: (event: KeyboardEvent) => void,\n options: UseHotkeysOptions = {}\n): void {\n const { preventDefault = true, ignoreWhenTyping = true, enabled = true, target } = options\n\n // Keep latest handler in a ref so callers don't need to memoize.\n const handlerRef = React.useRef(handler)\n React.useEffect(() => {\n handlerRef.current = handler\n }, [handler])\n\n React.useEffect(() => {\n if (!enabled) return\n const resolvedTarget = resolveTarget(target)\n if (!resolvedTarget) return\n\n const combos = (Array.isArray(combo) ? combo : [combo]).map(parseCombo)\n const mac = isMac()\n\n const listener = (event: Event) => {\n const keyboardEvent = event as KeyboardEvent\n const matched = combos.find((parsed) => matches(parsed, keyboardEvent, mac))\n if (!matched) return\n\n if (ignoreWhenTyping && isEditable(keyboardEvent.target) && !hasModifier(keyboardEvent)) {\n return\n }\n\n if (preventDefault) keyboardEvent.preventDefault()\n handlerRef.current(keyboardEvent)\n }\n\n resolvedTarget.addEventListener('keydown', listener)\n return () => {\n resolvedTarget.removeEventListener('keydown', listener)\n }\n // `combo` is usually a stable string literal; if callers pass a new array every\n // render we join-stringify to avoid stale closures without surprising rerenders.\n }, [Array.isArray(combo) ? combo.join('|') : combo, enabled, ignoreWhenTyping, preventDefault, target])\n}\n\n/**\n * Render-helper: returns a platform-appropriate display string for a combo.\n * 'mod+k' → '⌘K' on macOS, 'Ctrl+K' elsewhere. Useful for `<CommandShortcut>`.\n */\nexport function formatHotkey(combo: string): string {\n const mac = isMac()\n return combo\n .split('+')\n .map((p) => {\n const t = p.trim().toLowerCase()\n if (t === 'mod') return mac ? '⌘' : 'Ctrl'\n if (t === 'cmd' || t === 'meta') return mac ? '⌘' : 'Win'\n if (t === 'ctrl' || t === 'control') return mac ? '⌃' : 'Ctrl'\n if (t === 'shift') return mac ? '⇧' : 'Shift'\n if (t === 'alt' || t === 'option' || t === 'opt') return mac ? '⌥' : 'Alt'\n if (t === 'enter' || t === 'return') return '↵'\n if (t === 'escape' || t === 'esc') return 'Esc'\n if (t === 'space') return 'Space'\n if (t === 'up') return '↑'\n if (t === 'down') return '↓'\n if (t === 'left') return '←'\n if (t === 'right') return '→'\n return t.length === 1 ? t.toUpperCase() : t\n })\n .join(mac ? '' : '+')\n}\n"]}