@parto-system-design/ui 1.1.11 → 1.1.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/brand/parto-logo.cjs +130 -0
- package/dist/components/brand/parto-logo.cjs.map +1 -0
- package/dist/components/brand/parto-logo.d.cts +38 -0
- package/dist/components/brand/parto-logo.d.ts +38 -0
- package/dist/components/brand/parto-logo.js +108 -0
- package/dist/components/brand/parto-logo.js.map +1 -0
- package/dist/components/charts/PartoAreaChart.cjs +579 -7
- package/dist/components/charts/PartoAreaChart.cjs.map +1 -1
- package/dist/components/charts/PartoAreaChart.js +564 -4
- package/dist/components/charts/PartoAreaChart.js.map +1 -1
- package/dist/components/charts/PartoBarChart.cjs +616 -7
- package/dist/components/charts/PartoBarChart.cjs.map +1 -1
- package/dist/components/charts/PartoBarChart.js +601 -4
- package/dist/components/charts/PartoBarChart.js.map +1 -1
- package/dist/components/charts/PartoLineChart.cjs +584 -7
- package/dist/components/charts/PartoLineChart.cjs.map +1 -1
- package/dist/components/charts/PartoLineChart.js +569 -4
- package/dist/components/charts/PartoLineChart.js.map +1 -1
- package/dist/components/charts/PartoPieChart.cjs +566 -7
- package/dist/components/charts/PartoPieChart.cjs.map +1 -1
- package/dist/components/charts/PartoPieChart.js +551 -4
- package/dist/components/charts/PartoPieChart.js.map +1 -1
- package/dist/components/ui/accordion.cjs +97 -0
- package/dist/components/ui/accordion.cjs.map +1 -0
- package/dist/components/ui/accordion.d.cts +22 -0
- package/dist/components/ui/accordion.d.ts +22 -0
- package/dist/components/ui/accordion.js +72 -0
- package/dist/components/ui/accordion.js.map +1 -0
- package/dist/{chunk-MMC6M35Q.cjs → components/ui/alert-dialog.cjs} +216 -22
- package/dist/components/ui/alert-dialog.cjs.map +1 -0
- package/dist/components/ui/alert-dialog.d.cts +17 -0
- package/dist/components/ui/alert-dialog.d.ts +17 -0
- package/dist/{chunk-3QYYPPFJ.js → components/ui/alert-dialog.js} +175 -10
- package/dist/components/ui/alert-dialog.js.map +1 -0
- package/dist/components/ui/alert-rule-card.cjs +289 -8
- package/dist/components/ui/alert-rule-card.cjs.map +1 -1
- package/dist/components/ui/alert-rule-card.d.cts +1 -1
- package/dist/components/ui/alert-rule-card.d.ts +1 -1
- package/dist/components/ui/alert-rule-card.js +271 -4
- package/dist/components/ui/alert-rule-card.js.map +1 -1
- package/dist/components/ui/alert.cjs +81 -0
- package/dist/components/ui/alert.cjs.map +1 -0
- package/dist/components/ui/alert.d.cts +11 -0
- package/dist/components/ui/alert.d.ts +11 -0
- package/dist/components/ui/alert.js +57 -0
- package/dist/components/ui/alert.js.map +1 -0
- package/dist/components/ui/app-bar.cjs +67 -0
- package/dist/components/ui/app-bar.cjs.map +1 -0
- package/dist/components/ui/app-bar.d.cts +22 -0
- package/dist/components/ui/app-bar.d.ts +22 -0
- package/dist/components/ui/app-bar.js +44 -0
- package/dist/components/ui/app-bar.js.map +1 -0
- package/dist/components/ui/avatar.cjs +66 -14
- package/dist/components/ui/avatar.cjs.map +1 -1
- package/dist/components/ui/avatar.js +47 -2
- package/dist/components/ui/avatar.js.map +1 -1
- package/dist/components/ui/badge.cjs +113 -9
- package/dist/components/ui/badge.cjs.map +1 -1
- package/dist/components/ui/badge.js +96 -2
- package/dist/components/ui/badge.js.map +1 -1
- package/dist/components/ui/breadcrumb.cjs +100 -0
- package/dist/components/ui/breadcrumb.cjs.map +1 -0
- package/dist/components/ui/breadcrumb.d.cts +35 -0
- package/dist/components/ui/breadcrumb.d.ts +35 -0
- package/dist/components/ui/breadcrumb.js +92 -0
- package/dist/components/ui/breadcrumb.js.map +1 -0
- package/dist/components/ui/button.cjs +304 -11
- package/dist/components/ui/button.cjs.map +1 -1
- package/dist/components/ui/button.d.cts +1 -1
- package/dist/components/ui/button.d.ts +1 -1
- package/dist/components/ui/button.js +306 -3
- package/dist/components/ui/button.js.map +1 -1
- package/dist/components/ui/calendar.cjs +401 -8
- package/dist/components/ui/calendar.cjs.map +1 -1
- package/dist/components/ui/calendar.js +404 -4
- package/dist/components/ui/calendar.js.map +1 -1
- package/dist/components/ui/card.cjs +154 -30
- package/dist/components/ui/card.cjs.map +1 -1
- package/dist/components/ui/card.js +131 -2
- package/dist/components/ui/card.js.map +1 -1
- package/dist/{chunk-CAJKSTXX.cjs → components/ui/checkbox.cjs} +10 -5
- package/dist/components/ui/checkbox.cjs.map +1 -0
- package/dist/components/ui/checkbox.d.cts +6 -0
- package/dist/components/ui/checkbox.d.ts +6 -0
- package/dist/{chunk-5JJSRGJD.js → components/ui/checkbox.js} +9 -4
- package/dist/components/ui/checkbox.js.map +1 -0
- package/dist/components/ui/concept-card.cjs +728 -11
- package/dist/components/ui/concept-card.cjs.map +1 -1
- package/dist/components/ui/concept-card.d.cts +2 -2
- package/dist/components/ui/concept-card.d.ts +2 -2
- package/dist/components/ui/concept-card.js +710 -7
- package/dist/components/ui/concept-card.js.map +1 -1
- package/dist/components/ui/data-table.cjs +1553 -10
- package/dist/components/ui/data-table.cjs.map +1 -1
- package/dist/components/ui/data-table.js +1537 -7
- package/dist/components/ui/data-table.js.map +1 -1
- package/dist/components/ui/dialog.cjs +119 -42
- package/dist/components/ui/dialog.cjs.map +1 -1
- package/dist/components/ui/dialog.js +92 -2
- package/dist/components/ui/dialog.js.map +1 -1
- package/dist/components/ui/dropdown-menu.cjs +268 -0
- package/dist/components/ui/dropdown-menu.cjs.map +1 -0
- package/dist/components/ui/dropdown-menu.d.cts +73 -0
- package/dist/components/ui/dropdown-menu.d.ts +73 -0
- package/dist/components/ui/dropdown-menu.js +232 -0
- package/dist/components/ui/dropdown-menu.js.map +1 -0
- package/dist/components/ui/filter-provider.cjs +70 -13
- package/dist/components/ui/filter-provider.cjs.map +1 -1
- package/dist/components/ui/filter-provider.js +51 -1
- package/dist/components/ui/filter-provider.js.map +1 -1
- package/dist/components/ui/form.cjs +169 -0
- package/dist/components/ui/form.cjs.map +1 -0
- package/dist/components/ui/form.d.cts +46 -0
- package/dist/components/ui/form.d.ts +46 -0
- package/dist/components/ui/form.js +139 -0
- package/dist/components/ui/form.js.map +1 -0
- package/dist/components/ui/input.cjs +135 -15
- package/dist/components/ui/input.cjs.map +1 -1
- package/dist/components/ui/input.d.cts +15 -0
- package/dist/components/ui/input.d.ts +15 -0
- package/dist/components/ui/input.js +116 -3
- package/dist/components/ui/input.js.map +1 -1
- package/dist/components/ui/iran-province-heat.cjs +328 -5
- package/dist/components/ui/iran-province-heat.cjs.map +1 -1
- package/dist/components/ui/iran-province-heat.js +312 -2
- package/dist/components/ui/iran-province-heat.js.map +1 -1
- package/dist/components/ui/label.cjs +52 -0
- package/dist/components/ui/label.cjs.map +1 -0
- package/dist/components/ui/label.d.cts +10 -0
- package/dist/components/ui/label.d.ts +10 -0
- package/dist/components/ui/label.js +30 -0
- package/dist/components/ui/label.js.map +1 -0
- package/dist/components/ui/page-card.cjs +627 -8
- package/dist/components/ui/page-card.cjs.map +1 -1
- package/dist/components/ui/page-card.d.cts +3 -2
- package/dist/components/ui/page-card.d.ts +3 -2
- package/dist/components/ui/page-card.js +611 -5
- package/dist/components/ui/page-card.js.map +1 -1
- package/dist/components/ui/page-header.cjs +299 -0
- package/dist/components/ui/page-header.cjs.map +1 -0
- package/dist/components/ui/page-header.d.cts +21 -0
- package/dist/components/ui/page-header.d.ts +21 -0
- package/dist/components/ui/page-header.js +277 -0
- package/dist/components/ui/page-header.js.map +1 -0
- package/dist/components/ui/password-input.cjs +168 -0
- package/dist/components/ui/password-input.cjs.map +1 -0
- package/dist/components/ui/password-input.d.cts +48 -0
- package/dist/components/ui/password-input.d.ts +48 -0
- package/dist/components/ui/password-input.js +146 -0
- package/dist/components/ui/password-input.js.map +1 -0
- package/dist/components/ui/popover.cjs +51 -18
- package/dist/components/ui/popover.cjs.map +1 -1
- package/dist/components/ui/popover.js +30 -2
- package/dist/components/ui/popover.js.map +1 -1
- package/dist/components/ui/progress.cjs +95 -0
- package/dist/components/ui/progress.cjs.map +1 -0
- package/dist/components/ui/progress.d.cts +18 -0
- package/dist/components/ui/progress.d.ts +18 -0
- package/dist/components/ui/progress.js +72 -0
- package/dist/components/ui/progress.js.map +1 -0
- package/dist/components/ui/radio-card.cjs +84 -0
- package/dist/components/ui/radio-card.cjs.map +1 -0
- package/dist/components/ui/radio-card.d.cts +12 -0
- package/dist/components/ui/radio-card.d.ts +12 -0
- package/dist/components/ui/radio-card.js +58 -0
- package/dist/components/ui/radio-card.js.map +1 -0
- package/dist/components/ui/radio-group.cjs +62 -0
- package/dist/components/ui/radio-group.cjs.map +1 -0
- package/dist/components/ui/radio-group.d.cts +7 -0
- package/dist/components/ui/radio-group.d.ts +7 -0
- package/dist/components/ui/radio-group.js +38 -0
- package/dist/components/ui/radio-group.js.map +1 -0
- package/dist/components/ui/saved-query-card.cjs +409 -7
- package/dist/components/ui/saved-query-card.cjs.map +1 -1
- package/dist/components/ui/saved-query-card.js +394 -4
- package/dist/components/ui/saved-query-card.js.map +1 -1
- package/dist/components/ui/scroll-area.cjs +79 -0
- package/dist/components/ui/scroll-area.cjs.map +1 -0
- package/dist/components/ui/scroll-area.d.cts +14 -0
- package/dist/components/ui/scroll-area.d.ts +14 -0
- package/dist/components/ui/scroll-area.js +56 -0
- package/dist/components/ui/scroll-area.js.map +1 -0
- package/dist/components/ui/select.cjs +242 -0
- package/dist/components/ui/select.cjs.map +1 -0
- package/dist/components/ui/select.d.cts +29 -0
- package/dist/components/ui/select.d.ts +29 -0
- package/dist/components/ui/select.js +210 -0
- package/dist/components/ui/select.js.map +1 -0
- package/dist/components/ui/separator.cjs +105 -6
- package/dist/components/ui/separator.cjs.map +1 -1
- package/dist/components/ui/separator.js +87 -2
- package/dist/components/ui/separator.js.map +1 -1
- package/dist/components/ui/sheet.cjs +134 -38
- package/dist/components/ui/sheet.cjs.map +1 -1
- package/dist/components/ui/sheet.js +109 -2
- package/dist/components/ui/sheet.js.map +1 -1
- package/dist/{chunk-D2EBLE2B.cjs → components/ui/skeleton.cjs} +21 -16
- package/dist/components/ui/skeleton.cjs.map +1 -0
- package/dist/components/ui/skeleton.d.cts +90 -0
- package/dist/components/ui/skeleton.d.ts +90 -0
- package/dist/{chunk-SB5DSYR5.js → components/ui/skeleton.js} +8 -3
- package/dist/components/ui/skeleton.js.map +1 -0
- package/dist/components/ui/slider.cjs +129 -0
- package/dist/components/ui/slider.cjs.map +1 -0
- package/dist/components/ui/slider.d.cts +10 -0
- package/dist/components/ui/slider.d.ts +10 -0
- package/dist/components/ui/slider.js +107 -0
- package/dist/components/ui/slider.js.map +1 -0
- package/dist/components/ui/social-platform-badge.cjs +120 -0
- package/dist/components/ui/social-platform-badge.cjs.map +1 -0
- package/dist/components/ui/social-platform-badge.d.cts +21 -0
- package/dist/components/ui/social-platform-badge.d.ts +21 -0
- package/dist/components/ui/social-platform-badge.js +97 -0
- package/dist/components/ui/social-platform-badge.js.map +1 -0
- package/dist/components/ui/sonner.cjs +51 -0
- package/dist/components/ui/sonner.cjs.map +1 -0
- package/dist/components/ui/sonner.d.cts +13 -0
- package/dist/components/ui/sonner.d.ts +13 -0
- package/dist/components/ui/sonner.js +45 -0
- package/dist/components/ui/sonner.js.map +1 -0
- package/dist/components/ui/sparkline.cjs +159 -6
- package/dist/components/ui/sparkline.cjs.map +1 -1
- package/dist/components/ui/sparkline.js +142 -2
- package/dist/components/ui/sparkline.js.map +1 -1
- package/dist/components/ui/switch.cjs +96 -0
- package/dist/components/ui/switch.cjs.map +1 -0
- package/dist/components/ui/switch.d.cts +13 -0
- package/dist/components/ui/switch.d.ts +13 -0
- package/dist/components/ui/switch.js +73 -0
- package/dist/components/ui/switch.js.map +1 -0
- package/dist/components/ui/table.cjs +188 -0
- package/dist/components/ui/table.cjs.map +1 -0
- package/dist/components/ui/table.d.cts +59 -0
- package/dist/components/ui/table.d.ts +59 -0
- package/dist/components/ui/table.js +178 -0
- package/dist/components/ui/table.js.map +1 -0
- package/dist/components/ui/tabs.cjs +140 -0
- package/dist/components/ui/tabs.cjs.map +1 -0
- package/dist/components/ui/tabs.d.cts +21 -0
- package/dist/components/ui/tabs.d.ts +21 -0
- package/dist/components/ui/tabs.js +115 -0
- package/dist/components/ui/tabs.js.map +1 -0
- package/dist/components/ui/textarea.cjs +56 -0
- package/dist/components/ui/textarea.cjs.map +1 -0
- package/dist/components/ui/textarea.d.cts +5 -0
- package/dist/components/ui/textarea.d.ts +5 -0
- package/dist/components/ui/textarea.js +34 -0
- package/dist/components/ui/textarea.js.map +1 -0
- package/dist/components/ui/toggle-group.cjs +123 -0
- package/dist/components/ui/toggle-group.cjs.map +1 -0
- package/dist/components/ui/toggle-group.d.cts +7 -0
- package/dist/components/ui/toggle-group.d.ts +7 -0
- package/dist/components/ui/toggle-group.js +99 -0
- package/dist/components/ui/toggle-group.js.map +1 -0
- package/dist/components/ui/tooltip.cjs +77 -18
- package/dist/components/ui/tooltip.cjs.map +1 -1
- package/dist/components/ui/tooltip.js +56 -2
- package/dist/components/ui/tooltip.js.map +1 -1
- package/dist/{concept-card-RwPbqJ06.d.cts → concept-card-BXra9mr0.d.cts} +2 -2
- package/dist/{concept-card-CcOBb2Nz.d.ts → concept-card-BoJ5gIJD.d.ts} +2 -2
- package/dist/hooks/use-hotkey-registry.cjs +201 -14
- package/dist/hooks/use-hotkey-registry.cjs.map +1 -1
- package/dist/hooks/use-hotkey-registry.js +182 -2
- package/dist/hooks/use-hotkey-registry.js.map +1 -1
- package/dist/hooks/use-hotkeys.cjs +144 -9
- package/dist/hooks/use-hotkeys.cjs.map +1 -1
- package/dist/hooks/use-hotkeys.js +126 -1
- package/dist/hooks/use-hotkeys.js.map +1 -1
- package/dist/{i18n-CAd9wGOr.d.cts → i18n-BfRhV5aw.d.cts} +5 -3
- package/dist/{i18n-ArS3mqj0.d.ts → i18n-ewyqbKM-.d.ts} +5 -3
- package/dist/index.cjs +21003 -15720
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +412 -71
- package/dist/index.d.cts +82 -490
- package/dist/index.d.ts +82 -490
- package/dist/index.js +6727 -976
- package/dist/index.js.map +1 -1
- package/dist/{page-card-CmShVqG-.d.cts → page-card-C9XXXOVr.d.cts} +3 -20
- package/dist/{page-card-HBn-cy4J.d.ts → page-card-DAnbez_f.d.ts} +3 -20
- package/dist/toggle-group-B8r4LOQw.d.cts +26 -0
- package/dist/toggle-group-B8r4LOQw.d.ts +26 -0
- package/package.json +132 -2
- package/tailwind.config.ts +45 -0
- package/dist/chunk-2ACKKPWA.cjs +0 -112
- package/dist/chunk-2ACKKPWA.cjs.map +0 -1
- package/dist/chunk-2UD3LGVX.cjs +0 -316
- package/dist/chunk-2UD3LGVX.cjs.map +0 -1
- package/dist/chunk-3QYYPPFJ.js.map +0 -1
- package/dist/chunk-4SVQNEVH.js +0 -173
- package/dist/chunk-4SVQNEVH.js.map +0 -1
- package/dist/chunk-4WONHORR.cjs +0 -152
- package/dist/chunk-4WONHORR.cjs.map +0 -1
- package/dist/chunk-5HCXH6GS.js +0 -409
- package/dist/chunk-5HCXH6GS.js.map +0 -1
- package/dist/chunk-5JJSRGJD.js.map +0 -1
- package/dist/chunk-5K6E4ZSW.cjs +0 -77
- package/dist/chunk-5K6E4ZSW.cjs.map +0 -1
- package/dist/chunk-5NY26ULO.js +0 -89
- package/dist/chunk-5NY26ULO.js.map +0 -1
- package/dist/chunk-7RVPG3LE.cjs +0 -231
- package/dist/chunk-7RVPG3LE.cjs.map +0 -1
- package/dist/chunk-AYEK3WOM.js +0 -207
- package/dist/chunk-AYEK3WOM.js.map +0 -1
- package/dist/chunk-BRMBLIQG.js +0 -53
- package/dist/chunk-BRMBLIQG.js.map +0 -1
- package/dist/chunk-CAJKSTXX.cjs.map +0 -1
- package/dist/chunk-CKFWMHQU.js +0 -401
- package/dist/chunk-CKFWMHQU.js.map +0 -1
- package/dist/chunk-CV3N3HVK.js +0 -672
- package/dist/chunk-CV3N3HVK.js.map +0 -1
- package/dist/chunk-D2EBLE2B.cjs.map +0 -1
- package/dist/chunk-GCZ6YATL.js +0 -940
- package/dist/chunk-GCZ6YATL.js.map +0 -1
- package/dist/chunk-GKRAZGDI.cjs +0 -84
- package/dist/chunk-GKRAZGDI.cjs.map +0 -1
- package/dist/chunk-GPYJ66CG.js +0 -45
- package/dist/chunk-GPYJ66CG.js.map +0 -1
- package/dist/chunk-HF6XU5NI.js +0 -84
- package/dist/chunk-HF6XU5NI.js.map +0 -1
- package/dist/chunk-HJPDZOMJ.cjs +0 -87
- package/dist/chunk-HJPDZOMJ.cjs.map +0 -1
- package/dist/chunk-HS3XI3CC.cjs +0 -69
- package/dist/chunk-HS3XI3CC.cjs.map +0 -1
- package/dist/chunk-HUCC3QH5.cjs +0 -53
- package/dist/chunk-HUCC3QH5.cjs.map +0 -1
- package/dist/chunk-HYZ6BQPS.cjs +0 -425
- package/dist/chunk-HYZ6BQPS.cjs.map +0 -1
- package/dist/chunk-ISCSZMYW.cjs +0 -106
- package/dist/chunk-ISCSZMYW.cjs.map +0 -1
- package/dist/chunk-IXFEFIDO.js +0 -82
- package/dist/chunk-IXFEFIDO.js.map +0 -1
- package/dist/chunk-JCJLN437.js +0 -108
- package/dist/chunk-JCJLN437.js.map +0 -1
- package/dist/chunk-JMKNNH63.cjs +0 -982
- package/dist/chunk-JMKNNH63.cjs.map +0 -1
- package/dist/chunk-JUBHQAA2.js +0 -53
- package/dist/chunk-JUBHQAA2.js.map +0 -1
- package/dist/chunk-K6G63EED.cjs +0 -41
- package/dist/chunk-K6G63EED.cjs.map +0 -1
- package/dist/chunk-KCWRCSI7.js +0 -62
- package/dist/chunk-KCWRCSI7.js.map +0 -1
- package/dist/chunk-KYM7NIJO.cjs +0 -433
- package/dist/chunk-KYM7NIJO.cjs.map +0 -1
- package/dist/chunk-L2L5CKC2.js +0 -291
- package/dist/chunk-L2L5CKC2.js.map +0 -1
- package/dist/chunk-M5CHZ5BA.js +0 -124
- package/dist/chunk-M5CHZ5BA.js.map +0 -1
- package/dist/chunk-MEK4RSGC.js +0 -65
- package/dist/chunk-MEK4RSGC.js.map +0 -1
- package/dist/chunk-MEKWH3GS.js +0 -89
- package/dist/chunk-MEKWH3GS.js.map +0 -1
- package/dist/chunk-MFTX2DDQ.js +0 -27
- package/dist/chunk-MFTX2DDQ.js.map +0 -1
- package/dist/chunk-MMC6M35Q.cjs.map +0 -1
- package/dist/chunk-NMH43BDC.js +0 -130
- package/dist/chunk-NMH43BDC.js.map +0 -1
- package/dist/chunk-NORDUD2T.cjs +0 -135
- package/dist/chunk-NORDUD2T.cjs.map +0 -1
- package/dist/chunk-NV4JOKWL.cjs +0 -197
- package/dist/chunk-NV4JOKWL.cjs.map +0 -1
- package/dist/chunk-O2JG7WY5.cjs +0 -121
- package/dist/chunk-O2JG7WY5.cjs.map +0 -1
- package/dist/chunk-ONO2FTV4.cjs +0 -68
- package/dist/chunk-ONO2FTV4.cjs.map +0 -1
- package/dist/chunk-OQB6HIUL.cjs +0 -108
- package/dist/chunk-OQB6HIUL.cjs.map +0 -1
- package/dist/chunk-OS6CMYAS.cjs +0 -79
- package/dist/chunk-OS6CMYAS.cjs.map +0 -1
- package/dist/chunk-PYURPUTV.js +0 -402
- package/dist/chunk-PYURPUTV.js.map +0 -1
- package/dist/chunk-RJ3HYZ7S.js +0 -44
- package/dist/chunk-RJ3HYZ7S.js.map +0 -1
- package/dist/chunk-RZNRIOLT.js +0 -128
- package/dist/chunk-RZNRIOLT.js.map +0 -1
- package/dist/chunk-S3T2L6NA.js +0 -38
- package/dist/chunk-S3T2L6NA.js.map +0 -1
- package/dist/chunk-S5IPJQZ3.cjs +0 -161
- package/dist/chunk-S5IPJQZ3.cjs.map +0 -1
- package/dist/chunk-SB5DSYR5.js.map +0 -1
- package/dist/chunk-SFXV2DUH.js +0 -106
- package/dist/chunk-SFXV2DUH.js.map +0 -1
- package/dist/chunk-SXEPGD4Z.cjs +0 -152
- package/dist/chunk-SXEPGD4Z.cjs.map +0 -1
- package/dist/chunk-SXWSOU3Y.js +0 -89
- package/dist/chunk-SXWSOU3Y.js.map +0 -1
- package/dist/chunk-SZMVOHT7.cjs +0 -107
- package/dist/chunk-SZMVOHT7.cjs.map +0 -1
- package/dist/chunk-TWJXOV4C.js +0 -145
- package/dist/chunk-TWJXOV4C.js.map +0 -1
- package/dist/chunk-U3ADRIVO.cjs +0 -434
- package/dist/chunk-U3ADRIVO.cjs.map +0 -1
- package/dist/chunk-U5FLLCGC.cjs +0 -151
- package/dist/chunk-U5FLLCGC.cjs.map +0 -1
- package/dist/chunk-UOZN45G4.cjs +0 -130
- package/dist/chunk-UOZN45G4.cjs.map +0 -1
- package/dist/chunk-VHLDOG74.cjs +0 -167
- package/dist/chunk-VHLDOG74.cjs.map +0 -1
- package/dist/chunk-YC5KLN6I.js +0 -139
- package/dist/chunk-YC5KLN6I.js.map +0 -1
- package/dist/chunk-YENXXYUV.cjs +0 -111
- package/dist/chunk-YENXXYUV.cjs.map +0 -1
- package/dist/chunk-YFQWC2PW.js +0 -113
- package/dist/chunk-YFQWC2PW.js.map +0 -1
- package/dist/chunk-Z2TY4A75.cjs +0 -700
- package/dist/chunk-Z2TY4A75.cjs.map +0 -1
- package/dist/chunk-Z56O7UEU.cjs +0 -136
- package/dist/chunk-Z56O7UEU.cjs.map +0 -1
- package/dist/chunk-ZBZDR4ZC.js +0 -106
- package/dist/chunk-ZBZDR4ZC.js.map +0 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var clsx = require('clsx');
|
|
6
|
+
var tailwindMerge = require('tailwind-merge');
|
|
7
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
8
|
+
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n.default = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
28
|
+
|
|
29
|
+
function cn(...inputs) {
|
|
30
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
31
|
+
}
|
|
32
|
+
var Textarea = React__namespace.forwardRef(
|
|
33
|
+
({ className, ...props }, ref) => {
|
|
34
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
35
|
+
"textarea",
|
|
36
|
+
{
|
|
37
|
+
ref,
|
|
38
|
+
"data-slot": "textarea",
|
|
39
|
+
className: cn(
|
|
40
|
+
"flex field-sizing-content min-h-16 w-full rounded-md border border-control bg-foreground/[.026] px-3 py-2 text-sm text-foreground placeholder:text-foreground-lighter",
|
|
41
|
+
"transition-colors duration-150",
|
|
42
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
43
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
44
|
+
"aria-[invalid=true]:bg-destructive-200 dark:aria-[invalid=true]:bg-destructive/5 aria-[invalid=true]:border-destructive-400 dark:aria-[invalid=true]:border-destructive-default aria-[invalid=true]:focus:border-destructive aria-[invalid=true]:focus-visible:border-destructive",
|
|
45
|
+
className
|
|
46
|
+
),
|
|
47
|
+
...props
|
|
48
|
+
}
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
);
|
|
52
|
+
Textarea.displayName = "Textarea";
|
|
53
|
+
|
|
54
|
+
exports.Textarea = Textarea;
|
|
55
|
+
//# sourceMappingURL=textarea.cjs.map
|
|
56
|
+
//# sourceMappingURL=textarea.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/textarea.tsx"],"names":["twMerge","clsx","React","jsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAIO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACAA,IAAM,QAAA,GAAiBC,gBAAA,CAAA,UAAA;AAAA,EACrB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAChC,IAAA,uBACEC,cAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,WAAA,EAAU,UAAA;AAAA,QACV,SAAA,EAAW,EAAA;AAAA,UACT,uKAAA;AAAA,UACA,gCAAA;AAAA,UACA,0IAAA;AAAA,UACA,iDAAA;AAAA,UACA,mRAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"textarea.cjs","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\nconst Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<'textarea'>>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n 'flex field-sizing-content min-h-16 w-full rounded-md border border-control bg-foreground/[.026] px-3 py-2 text-sm text-foreground placeholder:text-foreground-lighter',\n 'transition-colors duration-150',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'aria-[invalid=true]:bg-destructive-200 dark:aria-[invalid=true]:bg-destructive/5 aria-[invalid=true]:border-destructive-400 dark:aria-[invalid=true]:border-destructive-default aria-[invalid=true]:focus:border-destructive aria-[invalid=true]:focus-visible:border-destructive',\n className\n )}\n {...props}\n />\n )\n }\n)\n\nTextarea.displayName = 'Textarea'\n\nexport { Textarea }\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { clsx } from 'clsx';
|
|
4
|
+
import { twMerge } from 'tailwind-merge';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function cn(...inputs) {
|
|
8
|
+
return twMerge(clsx(inputs));
|
|
9
|
+
}
|
|
10
|
+
var Textarea = React.forwardRef(
|
|
11
|
+
({ className, ...props }, ref) => {
|
|
12
|
+
return /* @__PURE__ */ jsx(
|
|
13
|
+
"textarea",
|
|
14
|
+
{
|
|
15
|
+
ref,
|
|
16
|
+
"data-slot": "textarea",
|
|
17
|
+
className: cn(
|
|
18
|
+
"flex field-sizing-content min-h-16 w-full rounded-md border border-control bg-foreground/[.026] px-3 py-2 text-sm text-foreground placeholder:text-foreground-lighter",
|
|
19
|
+
"transition-colors duration-150",
|
|
20
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background",
|
|
21
|
+
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
22
|
+
"aria-[invalid=true]:bg-destructive-200 dark:aria-[invalid=true]:bg-destructive/5 aria-[invalid=true]:border-destructive-400 dark:aria-[invalid=true]:border-destructive-default aria-[invalid=true]:focus:border-destructive aria-[invalid=true]:focus-visible:border-destructive",
|
|
23
|
+
className
|
|
24
|
+
),
|
|
25
|
+
...props
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
Textarea.displayName = "Textarea";
|
|
31
|
+
|
|
32
|
+
export { Textarea };
|
|
33
|
+
//# sourceMappingURL=textarea.js.map
|
|
34
|
+
//# sourceMappingURL=textarea.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/textarea.tsx"],"names":[],"mappings":";;;;;AAIO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACAA,IAAM,QAAA,GAAiB,KAAA,CAAA,UAAA;AAAA,EACrB,CAAC,EAAE,SAAA,EAAW,GAAG,KAAA,IAAS,GAAA,KAAQ;AAChC,IAAA,uBACE,GAAA;AAAA,MAAC,UAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,WAAA,EAAU,UAAA;AAAA,QACV,SAAA,EAAW,EAAA;AAAA,UACT,uKAAA;AAAA,UACA,gCAAA;AAAA,UACA,0IAAA;AAAA,UACA,iDAAA;AAAA,UACA,mRAAA;AAAA,UACA;AAAA,SACF;AAAA,QACC,GAAG;AAAA;AAAA,KACN;AAAA,EAEJ;AACF;AAEA,QAAA,CAAS,WAAA,GAAc,UAAA","file":"textarea.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\nconst Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<'textarea'>>(\n ({ className, ...props }, ref) => {\n return (\n <textarea\n ref={ref}\n data-slot=\"textarea\"\n className={cn(\n 'flex field-sizing-content min-h-16 w-full rounded-md border border-control bg-foreground/[.026] px-3 py-2 text-sm text-foreground placeholder:text-foreground-lighter',\n 'transition-colors duration-150',\n 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background',\n 'disabled:cursor-not-allowed disabled:opacity-50',\n 'aria-[invalid=true]:bg-destructive-200 dark:aria-[invalid=true]:bg-destructive/5 aria-[invalid=true]:border-destructive-400 dark:aria-[invalid=true]:border-destructive-default aria-[invalid=true]:focus:border-destructive aria-[invalid=true]:focus-visible:border-destructive',\n className\n )}\n {...props}\n />\n )\n }\n)\n\nTextarea.displayName = 'Textarea'\n\nexport { Textarea }\n"]}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var ToggleGroupPrimitive = require('@radix-ui/react-toggle-group');
|
|
6
|
+
var clsx = require('clsx');
|
|
7
|
+
var tailwindMerge = require('tailwind-merge');
|
|
8
|
+
require('@radix-ui/react-toggle');
|
|
9
|
+
var classVarianceAuthority = require('class-variance-authority');
|
|
10
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
11
|
+
|
|
12
|
+
function _interopNamespace(e) {
|
|
13
|
+
if (e && e.__esModule) return e;
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
31
|
+
var ToggleGroupPrimitive__namespace = /*#__PURE__*/_interopNamespace(ToggleGroupPrimitive);
|
|
32
|
+
|
|
33
|
+
function cn(...inputs) {
|
|
34
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
35
|
+
}
|
|
36
|
+
var toggleVariants = classVarianceAuthority.cva(
|
|
37
|
+
// 1.1.16 — hover keeps text at --foreground (not muted), so the
|
|
38
|
+
// element brightens on interaction instead of looking disabled.
|
|
39
|
+
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium text-foreground-light hover:text-foreground disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-background-control focus-visible:ring-offset-2 transition-all duration-150 active:scale-[0.97] whitespace-nowrap",
|
|
40
|
+
{
|
|
41
|
+
variants: {
|
|
42
|
+
variant: {
|
|
43
|
+
// Default — standalone toggle button. Accent fill on active.
|
|
44
|
+
default: "bg-transparent hover:bg-muted data-[state=on]:bg-accent data-[state=on]:text-foreground",
|
|
45
|
+
outline: "border border-control bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
46
|
+
// Segmented — designed to sit inside a ToggleGroup track
|
|
47
|
+
// (bg-surface-200). Active drops to page bg with a small shadow,
|
|
48
|
+
// i.e. the iOS / Stripe segmented-control pattern. Inactive items
|
|
49
|
+
// stay transparent so the track shows through.
|
|
50
|
+
segmented: "bg-transparent data-[state=on]:bg-background data-[state=on]:shadow-sm data-[state=on]:text-foreground"
|
|
51
|
+
},
|
|
52
|
+
size: {
|
|
53
|
+
default: "h-9 px-2 min-w-9",
|
|
54
|
+
sm: "h-8 px-1.5 min-w-8",
|
|
55
|
+
lg: "h-10 px-2.5 min-w-10"
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
defaultVariants: {
|
|
59
|
+
variant: "default",
|
|
60
|
+
size: "sm"
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
var ToggleGroupContext = React__namespace.createContext({
|
|
65
|
+
size: "sm",
|
|
66
|
+
variant: "default"
|
|
67
|
+
});
|
|
68
|
+
function ToggleGroup({
|
|
69
|
+
className,
|
|
70
|
+
variant,
|
|
71
|
+
size,
|
|
72
|
+
children,
|
|
73
|
+
...props
|
|
74
|
+
}) {
|
|
75
|
+
const isSingle = props.type === "single";
|
|
76
|
+
const isSegmented = variant === "segmented" || variant === void 0 && isSingle;
|
|
77
|
+
const effectiveVariant = isSegmented ? "segmented" : variant;
|
|
78
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
79
|
+
ToggleGroupPrimitive__namespace.Root,
|
|
80
|
+
{
|
|
81
|
+
"data-slot": "toggle-group",
|
|
82
|
+
"data-variant": effectiveVariant,
|
|
83
|
+
className: cn(
|
|
84
|
+
"flex items-center",
|
|
85
|
+
isSegmented ? "gap-0 rounded-md bg-surface-200 p-0.5 [&>*]:flex-1" : "justify-center gap-1",
|
|
86
|
+
className
|
|
87
|
+
),
|
|
88
|
+
...props,
|
|
89
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ToggleGroupContext.Provider, { value: { variant: effectiveVariant, size }, children })
|
|
90
|
+
}
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
function ToggleGroupItem({
|
|
94
|
+
className,
|
|
95
|
+
children,
|
|
96
|
+
variant,
|
|
97
|
+
size,
|
|
98
|
+
...props
|
|
99
|
+
}) {
|
|
100
|
+
const context = React__namespace.useContext(ToggleGroupContext);
|
|
101
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
102
|
+
ToggleGroupPrimitive__namespace.Item,
|
|
103
|
+
{
|
|
104
|
+
"data-slot": "toggle-group-item",
|
|
105
|
+
className: cn(
|
|
106
|
+
toggleVariants({
|
|
107
|
+
variant: context.variant || variant,
|
|
108
|
+
size: context.size || size
|
|
109
|
+
}),
|
|
110
|
+
className
|
|
111
|
+
),
|
|
112
|
+
...props,
|
|
113
|
+
children
|
|
114
|
+
}
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
ToggleGroup.displayName = "ToggleGroup";
|
|
118
|
+
ToggleGroupItem.displayName = "ToggleGroupItem";
|
|
119
|
+
|
|
120
|
+
exports.ToggleGroup = ToggleGroup;
|
|
121
|
+
exports.ToggleGroupItem = ToggleGroupItem;
|
|
122
|
+
//# sourceMappingURL=toggle-group.cjs.map
|
|
123
|
+
//# sourceMappingURL=toggle-group.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/toggle.tsx","../../../src/components/ui/toggle-group.tsx"],"names":["twMerge","clsx","cva","React","jsx","ToggleGroupPrimitive"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACEA,IAAM,cAAA,GAAiBC,0BAAA;AAAA;AAAA;AAAA,EAGrB,ibAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA;AAAA,QAEP,OAAA,EAAS,yFAAA;AAAA,QACT,OAAA,EAAS,6FAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAKT,SAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,kBAAA;AAAA,QACT,EAAA,EAAI,oBAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AC3BA,IAAM,qBAA2BC,gBAAA,CAAA,aAAA,CAAmD;AAAA,EAClF,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,EAAS;AACX,CAAC,CAAA;AAED,SAAS,WAAA,CAAY;AAAA,EACnB,SAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiG;AAQ/F,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,KAAS,QAAA;AAChC,EAAA,MAAM,WAAA,GAAc,OAAA,KAAY,WAAA,IAAgB,OAAA,KAAY,MAAA,IAAa,QAAA;AACzE,EAAA,MAAM,gBAAA,GAAmB,cAAc,WAAA,GAAc,OAAA;AAErD,EAAA,uBACEC,cAAAA;AAAA,IAAsBC,+BAAA,CAAA,IAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,cAAA,EAAc,gBAAA;AAAA,MACd,SAAA,EAAW,EAAA;AAAA,QACT,mBAAA;AAAA,QACA,cAAc,oDAAA,GAAuD,sBAAA;AAAA,QACrE;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAAD,cAAAA,CAAC,kBAAA,CAAmB,QAAA,EAAnB,EAA4B,KAAA,EAAO,EAAE,OAAA,EAAS,gBAAA,EAAkB,IAAA,EAAK,EAAI,QAAA,EAAS;AAAA;AAAA,GACrF;AAEJ;AAEA,SAAS,eAAA,CAAgB;AAAA,EACvB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiG;AAC/F,EAAA,MAAM,OAAA,GAAgBD,4BAAW,kBAAkB,CAAA;AAEnD,EAAA,uBACEC,cAAAA;AAAA,IAAsBC,+BAAA,CAAA,IAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,mBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,cAAA,CAAe;AAAA,UACb,OAAA,EAAS,QAAQ,OAAA,IAAW,OAAA;AAAA,UAC5B,IAAA,EAAM,QAAQ,IAAA,IAAQ;AAAA,SACvB,CAAA;AAAA,QACD;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA;AAC1B,eAAA,CAAgB,WAAA,GAAc,iBAAA","file":"toggle-group.cjs","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'\nimport * as TogglePrimitive from '@radix-ui/react-toggle'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '@/lib/utils'\n\nconst toggleVariants = cva(\n // 1.1.16 — hover keeps text at --foreground (not muted), so the\n // element brightens on interaction instead of looking disabled.\n \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium text-foreground-light hover:text-foreground disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-background-control focus-visible:ring-offset-2 transition-all duration-150 active:scale-[0.97] whitespace-nowrap\",\n {\n variants: {\n variant: {\n // Default — standalone toggle button. Accent fill on active.\n default: 'bg-transparent hover:bg-muted data-[state=on]:bg-accent data-[state=on]:text-foreground',\n outline: 'border border-control bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',\n // Segmented — designed to sit inside a ToggleGroup track\n // (bg-surface-200). Active drops to page bg with a small shadow,\n // i.e. the iOS / Stripe segmented-control pattern. Inactive items\n // stay transparent so the track shows through.\n segmented:\n 'bg-transparent data-[state=on]:bg-background data-[state=on]:shadow-sm data-[state=on]:text-foreground',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'sm',\n },\n }\n)\n\nfunction Toggle({\n className,\n variant,\n size,\n ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive.Root data-slot=\"toggle\" className={cn(toggleVariants({ variant, size, className }))} {...props} />\n )\n}\n\nToggle.displayName = 'Toggle'\n\nexport { Toggle, toggleVariants }\n","'use client'\n\nimport * as React from 'react'\nimport * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'\n\nimport { cn } from '@/lib/utils'\nimport { toggleVariants } from './toggle'\nimport type { VariantProps } from 'class-variance-authority'\n\nconst ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({\n size: 'sm',\n variant: 'default',\n})\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants>) {\n // 1.1.16 — single-select groups default to the segmented-control pattern\n // (iOS / Stripe / our own Tabs default-variant): items sit inside a\n // bg-surface-200 track and the active item drops to bg-background with a\n // subtle shadow. This gives a clear \"you picked this one\" affordance for\n // preference fields like طول/شکلک/زبان. Multi-select groups keep the\n // pre-1.1.16 layout (independent gapped buttons) because they're not\n // mutually exclusive.\n const isSingle = props.type === 'single'\n const isSegmented = variant === 'segmented' || (variant === undefined && isSingle)\n const effectiveVariant = isSegmented ? 'segmented' : variant\n\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={effectiveVariant}\n className={cn(\n 'flex items-center',\n isSegmented ? 'gap-0 rounded-md bg-surface-200 p-0.5 [&>*]:flex-1' : 'justify-center gap-1',\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant: effectiveVariant, size }}>{children}</ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant,\n size,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n className={cn(\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n}\n\nToggleGroup.displayName = 'ToggleGroup'\nToggleGroupItem.displayName = 'ToggleGroupItem'\n\nexport { ToggleGroup, ToggleGroupItem }\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import 'react/jsx-runtime';
|
|
2
|
+
import 'react';
|
|
3
|
+
import '@radix-ui/react-toggle-group';
|
|
4
|
+
export { a as ToggleGroup, b as ToggleGroupItem } from '../../toggle-group-B8r4LOQw.cjs';
|
|
5
|
+
import 'class-variance-authority';
|
|
6
|
+
import 'class-variance-authority/types';
|
|
7
|
+
import '@radix-ui/react-toggle';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import 'react/jsx-runtime';
|
|
2
|
+
import 'react';
|
|
3
|
+
import '@radix-ui/react-toggle-group';
|
|
4
|
+
export { a as ToggleGroup, b as ToggleGroupItem } from '../../toggle-group-B8r4LOQw.js';
|
|
5
|
+
import 'class-variance-authority';
|
|
6
|
+
import 'class-variance-authority/types';
|
|
7
|
+
import '@radix-ui/react-toggle';
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import '@radix-ui/react-toggle';
|
|
7
|
+
import { cva } from 'class-variance-authority';
|
|
8
|
+
import { jsx } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return twMerge(clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
var toggleVariants = cva(
|
|
14
|
+
// 1.1.16 — hover keeps text at --foreground (not muted), so the
|
|
15
|
+
// element brightens on interaction instead of looking disabled.
|
|
16
|
+
"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium text-foreground-light hover:text-foreground disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-background-control focus-visible:ring-offset-2 transition-all duration-150 active:scale-[0.97] whitespace-nowrap",
|
|
17
|
+
{
|
|
18
|
+
variants: {
|
|
19
|
+
variant: {
|
|
20
|
+
// Default — standalone toggle button. Accent fill on active.
|
|
21
|
+
default: "bg-transparent hover:bg-muted data-[state=on]:bg-accent data-[state=on]:text-foreground",
|
|
22
|
+
outline: "border border-control bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground",
|
|
23
|
+
// Segmented — designed to sit inside a ToggleGroup track
|
|
24
|
+
// (bg-surface-200). Active drops to page bg with a small shadow,
|
|
25
|
+
// i.e. the iOS / Stripe segmented-control pattern. Inactive items
|
|
26
|
+
// stay transparent so the track shows through.
|
|
27
|
+
segmented: "bg-transparent data-[state=on]:bg-background data-[state=on]:shadow-sm data-[state=on]:text-foreground"
|
|
28
|
+
},
|
|
29
|
+
size: {
|
|
30
|
+
default: "h-9 px-2 min-w-9",
|
|
31
|
+
sm: "h-8 px-1.5 min-w-8",
|
|
32
|
+
lg: "h-10 px-2.5 min-w-10"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
defaultVariants: {
|
|
36
|
+
variant: "default",
|
|
37
|
+
size: "sm"
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
);
|
|
41
|
+
var ToggleGroupContext = React.createContext({
|
|
42
|
+
size: "sm",
|
|
43
|
+
variant: "default"
|
|
44
|
+
});
|
|
45
|
+
function ToggleGroup({
|
|
46
|
+
className,
|
|
47
|
+
variant,
|
|
48
|
+
size,
|
|
49
|
+
children,
|
|
50
|
+
...props
|
|
51
|
+
}) {
|
|
52
|
+
const isSingle = props.type === "single";
|
|
53
|
+
const isSegmented = variant === "segmented" || variant === void 0 && isSingle;
|
|
54
|
+
const effectiveVariant = isSegmented ? "segmented" : variant;
|
|
55
|
+
return /* @__PURE__ */ jsx(
|
|
56
|
+
ToggleGroupPrimitive.Root,
|
|
57
|
+
{
|
|
58
|
+
"data-slot": "toggle-group",
|
|
59
|
+
"data-variant": effectiveVariant,
|
|
60
|
+
className: cn(
|
|
61
|
+
"flex items-center",
|
|
62
|
+
isSegmented ? "gap-0 rounded-md bg-surface-200 p-0.5 [&>*]:flex-1" : "justify-center gap-1",
|
|
63
|
+
className
|
|
64
|
+
),
|
|
65
|
+
...props,
|
|
66
|
+
children: /* @__PURE__ */ jsx(ToggleGroupContext.Provider, { value: { variant: effectiveVariant, size }, children })
|
|
67
|
+
}
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
function ToggleGroupItem({
|
|
71
|
+
className,
|
|
72
|
+
children,
|
|
73
|
+
variant,
|
|
74
|
+
size,
|
|
75
|
+
...props
|
|
76
|
+
}) {
|
|
77
|
+
const context = React.useContext(ToggleGroupContext);
|
|
78
|
+
return /* @__PURE__ */ jsx(
|
|
79
|
+
ToggleGroupPrimitive.Item,
|
|
80
|
+
{
|
|
81
|
+
"data-slot": "toggle-group-item",
|
|
82
|
+
className: cn(
|
|
83
|
+
toggleVariants({
|
|
84
|
+
variant: context.variant || variant,
|
|
85
|
+
size: context.size || size
|
|
86
|
+
}),
|
|
87
|
+
className
|
|
88
|
+
),
|
|
89
|
+
...props,
|
|
90
|
+
children
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
ToggleGroup.displayName = "ToggleGroup";
|
|
95
|
+
ToggleGroupItem.displayName = "ToggleGroupItem";
|
|
96
|
+
|
|
97
|
+
export { ToggleGroup, ToggleGroupItem };
|
|
98
|
+
//# sourceMappingURL=toggle-group.js.map
|
|
99
|
+
//# sourceMappingURL=toggle-group.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/toggle.tsx","../../../src/components/ui/toggle-group.tsx"],"names":["jsx"],"mappings":";;;;;;;;AAIO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAO,OAAA,CAAQ,IAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACEA,IAAM,cAAA,GAAiB,GAAA;AAAA;AAAA;AAAA,EAGrB,ibAAA;AAAA,EACA;AAAA,IACE,QAAA,EAAU;AAAA,MACR,OAAA,EAAS;AAAA;AAAA,QAEP,OAAA,EAAS,yFAAA;AAAA,QACT,OAAA,EAAS,6FAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAKT,SAAA,EACE;AAAA,OACJ;AAAA,MACA,IAAA,EAAM;AAAA,QACJ,OAAA,EAAS,kBAAA;AAAA,QACT,EAAA,EAAI,oBAAA;AAAA,QACJ,EAAA,EAAI;AAAA;AACN,KACF;AAAA,IACA,eAAA,EAAiB;AAAA,MACf,OAAA,EAAS,SAAA;AAAA,MACT,IAAA,EAAM;AAAA;AACR;AAEJ,CAAA;AC3BA,IAAM,qBAA2B,KAAA,CAAA,aAAA,CAAmD;AAAA,EAClF,IAAA,EAAM,IAAA;AAAA,EACN,OAAA,EAAS;AACX,CAAC,CAAA;AAED,SAAS,WAAA,CAAY;AAAA,EACnB,SAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiG;AAQ/F,EAAA,MAAM,QAAA,GAAW,MAAM,IAAA,KAAS,QAAA;AAChC,EAAA,MAAM,WAAA,GAAc,OAAA,KAAY,WAAA,IAAgB,OAAA,KAAY,MAAA,IAAa,QAAA;AACzE,EAAA,MAAM,gBAAA,GAAmB,cAAc,WAAA,GAAc,OAAA;AAErD,EAAA,uBACEA,GAAAA;AAAA,IAAsB,oBAAA,CAAA,IAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,cAAA;AAAA,MACV,cAAA,EAAc,gBAAA;AAAA,MACd,SAAA,EAAW,EAAA;AAAA,QACT,mBAAA;AAAA,QACA,cAAc,oDAAA,GAAuD,sBAAA;AAAA,QACrE;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAAA,GAAAA,CAAC,kBAAA,CAAmB,QAAA,EAAnB,EAA4B,KAAA,EAAO,EAAE,OAAA,EAAS,gBAAA,EAAkB,IAAA,EAAK,EAAI,QAAA,EAAS;AAAA;AAAA,GACrF;AAEJ;AAEA,SAAS,eAAA,CAAgB;AAAA,EACvB,SAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,IAAA;AAAA,EACA,GAAG;AACL,CAAA,EAAiG;AAC/F,EAAA,MAAM,OAAA,GAAgB,iBAAW,kBAAkB,CAAA;AAEnD,EAAA,uBACEA,GAAAA;AAAA,IAAsB,oBAAA,CAAA,IAAA;AAAA,IAArB;AAAA,MACC,WAAA,EAAU,mBAAA;AAAA,MACV,SAAA,EAAW,EAAA;AAAA,QACT,cAAA,CAAe;AAAA,UACb,OAAA,EAAS,QAAQ,OAAA,IAAW,OAAA;AAAA,UAC5B,IAAA,EAAM,QAAQ,IAAA,IAAQ;AAAA,SACvB,CAAA;AAAA,QACD;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH;AAAA;AAAA,GACH;AAEJ;AAEA,WAAA,CAAY,WAAA,GAAc,aAAA;AAC1B,eAAA,CAAgB,WAAA,GAAc,iBAAA","file":"toggle-group.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'\nimport * as TogglePrimitive from '@radix-ui/react-toggle'\nimport { cva, type VariantProps } from 'class-variance-authority'\n\nimport { cn } from '@/lib/utils'\n\nconst toggleVariants = cva(\n // 1.1.16 — hover keeps text at --foreground (not muted), so the\n // element brightens on interaction instead of looking disabled.\n \"inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium text-foreground-light hover:text-foreground disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 [&_svg]:shrink-0 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-background-control focus-visible:ring-offset-2 transition-all duration-150 active:scale-[0.97] whitespace-nowrap\",\n {\n variants: {\n variant: {\n // Default — standalone toggle button. Accent fill on active.\n default: 'bg-transparent hover:bg-muted data-[state=on]:bg-accent data-[state=on]:text-foreground',\n outline: 'border border-control bg-transparent shadow-xs hover:bg-accent hover:text-accent-foreground',\n // Segmented — designed to sit inside a ToggleGroup track\n // (bg-surface-200). Active drops to page bg with a small shadow,\n // i.e. the iOS / Stripe segmented-control pattern. Inactive items\n // stay transparent so the track shows through.\n segmented:\n 'bg-transparent data-[state=on]:bg-background data-[state=on]:shadow-sm data-[state=on]:text-foreground',\n },\n size: {\n default: 'h-9 px-2 min-w-9',\n sm: 'h-8 px-1.5 min-w-8',\n lg: 'h-10 px-2.5 min-w-10',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'sm',\n },\n }\n)\n\nfunction Toggle({\n className,\n variant,\n size,\n ...props\n}: React.ComponentProps<typeof TogglePrimitive.Root> & VariantProps<typeof toggleVariants>) {\n return (\n <TogglePrimitive.Root data-slot=\"toggle\" className={cn(toggleVariants({ variant, size, className }))} {...props} />\n )\n}\n\nToggle.displayName = 'Toggle'\n\nexport { Toggle, toggleVariants }\n","'use client'\n\nimport * as React from 'react'\nimport * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group'\n\nimport { cn } from '@/lib/utils'\nimport { toggleVariants } from './toggle'\nimport type { VariantProps } from 'class-variance-authority'\n\nconst ToggleGroupContext = React.createContext<VariantProps<typeof toggleVariants>>({\n size: 'sm',\n variant: 'default',\n})\n\nfunction ToggleGroup({\n className,\n variant,\n size,\n children,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Root> & VariantProps<typeof toggleVariants>) {\n // 1.1.16 — single-select groups default to the segmented-control pattern\n // (iOS / Stripe / our own Tabs default-variant): items sit inside a\n // bg-surface-200 track and the active item drops to bg-background with a\n // subtle shadow. This gives a clear \"you picked this one\" affordance for\n // preference fields like طول/شکلک/زبان. Multi-select groups keep the\n // pre-1.1.16 layout (independent gapped buttons) because they're not\n // mutually exclusive.\n const isSingle = props.type === 'single'\n const isSegmented = variant === 'segmented' || (variant === undefined && isSingle)\n const effectiveVariant = isSegmented ? 'segmented' : variant\n\n return (\n <ToggleGroupPrimitive.Root\n data-slot=\"toggle-group\"\n data-variant={effectiveVariant}\n className={cn(\n 'flex items-center',\n isSegmented ? 'gap-0 rounded-md bg-surface-200 p-0.5 [&>*]:flex-1' : 'justify-center gap-1',\n className\n )}\n {...props}\n >\n <ToggleGroupContext.Provider value={{ variant: effectiveVariant, size }}>{children}</ToggleGroupContext.Provider>\n </ToggleGroupPrimitive.Root>\n )\n}\n\nfunction ToggleGroupItem({\n className,\n children,\n variant,\n size,\n ...props\n}: React.ComponentProps<typeof ToggleGroupPrimitive.Item> & VariantProps<typeof toggleVariants>) {\n const context = React.useContext(ToggleGroupContext)\n\n return (\n <ToggleGroupPrimitive.Item\n data-slot=\"toggle-group-item\"\n className={cn(\n toggleVariants({\n variant: context.variant || variant,\n size: context.size || size,\n }),\n className\n )}\n {...props}\n >\n {children}\n </ToggleGroupPrimitive.Item>\n )\n}\n\nToggleGroup.displayName = 'ToggleGroup'\nToggleGroupItem.displayName = 'ToggleGroupItem'\n\nexport { ToggleGroup, ToggleGroupItem }\n"]}
|
|
@@ -1,25 +1,84 @@
|
|
|
1
|
+
'use client';
|
|
1
2
|
'use strict';
|
|
2
3
|
|
|
3
|
-
var
|
|
4
|
-
require('
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var TooltipPrimitive = require('@radix-ui/react-tooltip');
|
|
6
|
+
var clsx = require('clsx');
|
|
7
|
+
var tailwindMerge = require('tailwind-merge');
|
|
8
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
5
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
|
+
}
|
|
6
27
|
|
|
28
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
29
|
+
var TooltipPrimitive__namespace = /*#__PURE__*/_interopNamespace(TooltipPrimitive);
|
|
7
30
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
})
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
31
|
+
function cn(...inputs) {
|
|
32
|
+
return tailwindMerge.twMerge(clsx.clsx(inputs));
|
|
33
|
+
}
|
|
34
|
+
var TooltipProvider = TooltipPrimitive__namespace.Provider;
|
|
35
|
+
var Tooltip = TooltipPrimitive__namespace.Root;
|
|
36
|
+
var TooltipTrigger = TooltipPrimitive__namespace.Trigger;
|
|
37
|
+
var TooltipContent = React__namespace.forwardRef(
|
|
38
|
+
({ className, variant = "default", size = "sm", showArrow = false, sideOffset = 4, children, ...props }, ref) => /* @__PURE__ */ jsxRuntime.jsx(TooltipPrimitive__namespace.Portal, { children: /* @__PURE__ */ jsxRuntime.jsxs(
|
|
39
|
+
TooltipPrimitive__namespace.Content,
|
|
40
|
+
{
|
|
41
|
+
ref,
|
|
42
|
+
"data-slot": "tooltip-content",
|
|
43
|
+
sideOffset,
|
|
44
|
+
className: cn(
|
|
45
|
+
"z-50 overflow-hidden rounded-md shadow-dropdown",
|
|
46
|
+
"animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
|
47
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
48
|
+
// Variant styles
|
|
49
|
+
variant === "default" && "border bg-alternative text-foreground",
|
|
50
|
+
variant === "light" && "border bg-surface-100 text-foreground shadow-dropdown",
|
|
51
|
+
variant === "error" && "border border-destructive-500 bg-destructive-200 text-destructive-600",
|
|
52
|
+
// Size
|
|
53
|
+
size === "sm" && "px-3 py-1.5 text-xs",
|
|
54
|
+
size === "md" && "px-4 py-2 text-sm",
|
|
55
|
+
className
|
|
56
|
+
),
|
|
57
|
+
...props,
|
|
58
|
+
children: [
|
|
59
|
+
children,
|
|
60
|
+
showArrow && /* @__PURE__ */ jsxRuntime.jsx(
|
|
61
|
+
TooltipPrimitive__namespace.Arrow,
|
|
62
|
+
{
|
|
63
|
+
className: cn(
|
|
64
|
+
"fill-current",
|
|
65
|
+
variant === "default" && "text-alternative",
|
|
66
|
+
variant === "light" && "text-surface-100",
|
|
67
|
+
variant === "error" && "text-destructive-200"
|
|
68
|
+
),
|
|
69
|
+
width: 8,
|
|
70
|
+
height: 4
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
]
|
|
74
|
+
}
|
|
75
|
+
) })
|
|
76
|
+
);
|
|
77
|
+
TooltipContent.displayName = TooltipPrimitive__namespace.Content.displayName;
|
|
78
|
+
|
|
79
|
+
exports.Tooltip = Tooltip;
|
|
80
|
+
exports.TooltipContent = TooltipContent;
|
|
81
|
+
exports.TooltipProvider = TooltipProvider;
|
|
82
|
+
exports.TooltipTrigger = TooltipTrigger;
|
|
24
83
|
//# sourceMappingURL=tooltip.cjs.map
|
|
25
84
|
//# sourceMappingURL=tooltip.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"tooltip.cjs"}
|
|
1
|
+
{"version":3,"sources":["../../../src/lib/utils.ts","../../../src/components/ui/tooltip.tsx"],"names":["twMerge","clsx","TooltipPrimitive","React","jsx","jsxs"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIO,SAAS,MAAM,MAAA,EAAsB;AAC1C,EAAA,OAAOA,qBAAA,CAAQC,SAAA,CAAK,MAAM,CAAC,CAAA;AAC7B;ACCA,IAAM,eAAA,GAAmCC,2BAAA,CAAA;AAEzC,IAAM,OAAA,GAA2BA,2BAAA,CAAA;AAEjC,IAAM,cAAA,GAAkCA,2BAAA,CAAA;AAexC,IAAM,cAAA,GAAuBC,gBAAA,CAAA,UAAA;AAAA,EAC3B,CAAC,EAAE,SAAA,EAAW,UAAU,SAAA,EAAW,IAAA,GAAO,MAAM,SAAA,GAAY,KAAA,EAAO,UAAA,GAAa,CAAA,EAAG,UAAU,GAAG,KAAA,IAAS,GAAA,qBACvGC,cAAA,CAAkBF,oCAAjB,EACC,QAAA,kBAAAG,eAAA;AAAA,IAAkBH,2BAAA,CAAA,OAAA;AAAA,IAAjB;AAAA,MACC,GAAA;AAAA,MACA,WAAA,EAAU,iBAAA;AAAA,MACV,UAAA;AAAA,MACA,SAAA,EAAW,EAAA;AAAA,QACT,iDAAA;AAAA,QACA,mLAAA;AAAA,QACA,gGAAA;AAAA;AAAA,QAEA,YAAY,SAAA,IAAa,uCAAA;AAAA,QACzB,YAAY,OAAA,IAAW,uDAAA;AAAA,QACvB,YAAY,OAAA,IAAW,uEAAA;AAAA;AAAA,QAEvB,SAAS,IAAA,IAAQ,qBAAA;AAAA,QACjB,SAAS,IAAA,IAAQ,mBAAA;AAAA,QACjB;AAAA,OACF;AAAA,MACC,GAAG,KAAA;AAAA,MAEH,QAAA,EAAA;AAAA,QAAA,QAAA;AAAA,QACA,SAAA,oBACCE,cAAA;AAAA,UAAkBF,2BAAA,CAAA,KAAA;AAAA,UAAjB;AAAA,YACC,SAAA,EAAW,EAAA;AAAA,cACT,cAAA;AAAA,cACA,YAAY,SAAA,IAAa,kBAAA;AAAA,cACzB,YAAY,OAAA,IAAW,kBAAA;AAAA,cACvB,YAAY,OAAA,IAAW;AAAA,aACzB;AAAA,YACA,KAAA,EAAO,CAAA;AAAA,YACP,MAAA,EAAQ;AAAA;AAAA;AACV;AAAA;AAAA,GAEJ,EACF;AAEJ;AACA,cAAA,CAAe,cAA+BA,2BAAA,CAAA,OAAA,CAAQ,WAAA","file":"tooltip.cjs","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'\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\n\nimport { cn } from '@/lib/utils'\n\nconst TooltipProvider = TooltipPrimitive.Provider\n\nconst Tooltip = TooltipPrimitive.Root\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\n/* -------------------------------------------------------------------------- */\n/* TooltipContent */\n/* -------------------------------------------------------------------------- */\n\ninterface TooltipContentProps extends React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content> {\n /** Visual variant */\n variant?: 'default' | 'light' | 'error'\n /** Size */\n size?: 'sm' | 'md'\n /** Show arrow/caret pointing to trigger */\n showArrow?: boolean\n}\n\nconst TooltipContent = React.forwardRef<React.ElementRef<typeof TooltipPrimitive.Content>, TooltipContentProps>(\n ({ className, variant = 'default', size = 'sm', showArrow = false, sideOffset = 4, children, ...props }, ref) => (\n <TooltipPrimitive.Portal>\n <TooltipPrimitive.Content\n ref={ref}\n data-slot=\"tooltip-content\"\n sideOffset={sideOffset}\n className={cn(\n 'z-50 overflow-hidden rounded-md shadow-dropdown',\n 'animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1',\n 'data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95',\n // Variant styles\n variant === 'default' && 'border bg-alternative text-foreground',\n variant === 'light' && 'border bg-surface-100 text-foreground shadow-dropdown',\n variant === 'error' && 'border border-destructive-500 bg-destructive-200 text-destructive-600',\n // Size\n size === 'sm' && 'px-3 py-1.5 text-xs',\n size === 'md' && 'px-4 py-2 text-sm',\n className\n )}\n {...props}\n >\n {children}\n {showArrow && (\n <TooltipPrimitive.Arrow\n className={cn(\n 'fill-current',\n variant === 'default' && 'text-alternative',\n variant === 'light' && 'text-surface-100',\n variant === 'error' && 'text-destructive-200'\n )}\n width={8}\n height={4}\n />\n )}\n </TooltipPrimitive.Content>\n </TooltipPrimitive.Portal>\n )\n)\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }\n"]}
|
|
@@ -1,4 +1,58 @@
|
|
|
1
|
-
|
|
2
|
-
import '
|
|
1
|
+
'use client';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import * as TooltipPrimitive from '@radix-ui/react-tooltip';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function cn(...inputs) {
|
|
9
|
+
return twMerge(clsx(inputs));
|
|
10
|
+
}
|
|
11
|
+
var TooltipProvider = TooltipPrimitive.Provider;
|
|
12
|
+
var Tooltip = TooltipPrimitive.Root;
|
|
13
|
+
var TooltipTrigger = TooltipPrimitive.Trigger;
|
|
14
|
+
var TooltipContent = React.forwardRef(
|
|
15
|
+
({ className, variant = "default", size = "sm", showArrow = false, sideOffset = 4, children, ...props }, ref) => /* @__PURE__ */ jsx(TooltipPrimitive.Portal, { children: /* @__PURE__ */ jsxs(
|
|
16
|
+
TooltipPrimitive.Content,
|
|
17
|
+
{
|
|
18
|
+
ref,
|
|
19
|
+
"data-slot": "tooltip-content",
|
|
20
|
+
sideOffset,
|
|
21
|
+
className: cn(
|
|
22
|
+
"z-50 overflow-hidden rounded-md shadow-dropdown",
|
|
23
|
+
"animate-in fade-in-50 data-[side=bottom]:slide-in-from-top-1 data-[side=left]:slide-in-from-right-1 data-[side=right]:slide-in-from-left-1 data-[side=top]:slide-in-from-bottom-1",
|
|
24
|
+
"data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95",
|
|
25
|
+
// Variant styles
|
|
26
|
+
variant === "default" && "border bg-alternative text-foreground",
|
|
27
|
+
variant === "light" && "border bg-surface-100 text-foreground shadow-dropdown",
|
|
28
|
+
variant === "error" && "border border-destructive-500 bg-destructive-200 text-destructive-600",
|
|
29
|
+
// Size
|
|
30
|
+
size === "sm" && "px-3 py-1.5 text-xs",
|
|
31
|
+
size === "md" && "px-4 py-2 text-sm",
|
|
32
|
+
className
|
|
33
|
+
),
|
|
34
|
+
...props,
|
|
35
|
+
children: [
|
|
36
|
+
children,
|
|
37
|
+
showArrow && /* @__PURE__ */ jsx(
|
|
38
|
+
TooltipPrimitive.Arrow,
|
|
39
|
+
{
|
|
40
|
+
className: cn(
|
|
41
|
+
"fill-current",
|
|
42
|
+
variant === "default" && "text-alternative",
|
|
43
|
+
variant === "light" && "text-surface-100",
|
|
44
|
+
variant === "error" && "text-destructive-200"
|
|
45
|
+
),
|
|
46
|
+
width: 8,
|
|
47
|
+
height: 4
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
) })
|
|
53
|
+
);
|
|
54
|
+
TooltipContent.displayName = TooltipPrimitive.Content.displayName;
|
|
55
|
+
|
|
56
|
+
export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
|
|
3
57
|
//# sourceMappingURL=tooltip.js.map
|
|
4
58
|
//# sourceMappingURL=tooltip.js.map
|