@definable/ui 0.1.13 → 0.1.15

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 (300) hide show
  1. package/README.md +0 -7
  2. package/dist/components/alert-dialog.js +55 -2
  3. package/dist/components/alert.js +63 -2
  4. package/dist/components/avatar.js +41 -2
  5. package/dist/components/badge.js +26 -2
  6. package/dist/components/button.d.ts +2 -2
  7. package/dist/components/button.js +49 -2
  8. package/dist/components/calendar.js +86 -2
  9. package/dist/components/card.js +61 -2
  10. package/dist/components/carousel.js +100 -2
  11. package/dist/components/checkbox.js +31 -2
  12. package/dist/components/collapse.js +49 -2
  13. package/dist/components/command-menu.js +89 -2
  14. package/dist/components/command.js +115 -2
  15. package/dist/components/confirmation-modal.js +44 -2
  16. package/dist/components/context-menu.js +185 -2
  17. package/dist/components/dialog.js +121 -2
  18. package/dist/components/dropdown-menu.js +48 -2
  19. package/dist/components/dropzone.js +44 -2
  20. package/dist/components/image-cropper-modal.js +250 -2
  21. package/dist/components/image-cropper.js +130 -2
  22. package/dist/components/input.js +21 -2
  23. package/dist/components/label.js +19 -2
  24. package/dist/components/loader.js +69 -2
  25. package/dist/components/loading-placeholder.js +24 -2
  26. package/dist/components/mention.js +153 -2
  27. package/dist/components/modal.js +135 -2
  28. package/dist/components/notification.js +25 -2
  29. package/dist/components/popover.js +23 -2
  30. package/dist/components/progress.js +34 -2
  31. package/dist/components/radio-group.js +47 -2
  32. package/dist/components/scroll-area.js +46 -2
  33. package/dist/components/select.js +130 -2
  34. package/dist/components/selection-bar.js +53 -2
  35. package/dist/components/separator.js +24 -2
  36. package/dist/components/sheet.js +128 -2
  37. package/dist/components/skeleton.js +17 -2
  38. package/dist/components/slider.js +32 -2
  39. package/dist/components/stepper/index.d.ts +4 -0
  40. package/dist/components/stepper/step-layout.d.ts +8 -0
  41. package/dist/components/stepper/stepper-modal.d.ts +26 -0
  42. package/dist/components/stepper/stepper.d.ts +7 -0
  43. package/dist/components/stepper/types.d.ts +6 -0
  44. package/dist/components/stepper.js +6 -2
  45. package/dist/components/switch.js +35 -2
  46. package/dist/components/table-empty.js +22 -2
  47. package/dist/components/table-mobile.js +91 -2
  48. package/dist/components/table.js +156 -2
  49. package/dist/components/tabs.js +46 -2
  50. package/dist/components/terminal.js +49 -2
  51. package/dist/components/textarea.js +20 -2
  52. package/dist/components/tooltip.js +75 -2
  53. package/dist/components/use-toast.js +64 -2
  54. package/dist/icons/icons.d.ts +8 -0
  55. package/dist/icons/index.d.ts +1 -0
  56. package/dist/icons/providers/anthropic.d.ts +2 -0
  57. package/dist/icons/providers/claude.d.ts +2 -0
  58. package/dist/icons/providers/deepseek.d.ts +2 -0
  59. package/dist/icons/providers/gemini.d.ts +2 -0
  60. package/dist/icons/providers/grok.d.ts +2 -0
  61. package/dist/icons/providers/index.d.ts +6 -0
  62. package/dist/icons/providers/openai.d.ts +2 -0
  63. package/dist/icons/providers/types.d.ts +4 -0
  64. package/dist/index.d.ts +48 -962
  65. package/dist/index.js +444 -2
  66. package/dist/lib/icons.d.ts +14 -0
  67. package/dist/lib/index.d.ts +2 -0
  68. package/dist/lib/utils.js +8 -2
  69. package/dist/{stepper-modal-SYU9mbXs.js → stepper-modal-JXpOXOV2.js} +90 -91
  70. package/dist/styles.css +1 -1
  71. package/package.json +180 -134
  72. package/dist/MonacoEditor-COZcVMEj.cjs +0 -8
  73. package/dist/MonacoEditor-COZcVMEj.cjs.map +0 -1
  74. package/dist/MonacoEditor-D3QSSKa4.js +0 -295
  75. package/dist/MonacoEditor-D3QSSKa4.js.map +0 -1
  76. package/dist/alert-dialog.d.ts +0 -18
  77. package/dist/alert.d.ts +0 -25
  78. package/dist/avatar.d.ts +0 -9
  79. package/dist/badge.d.ts +0 -15
  80. package/dist/button.d.ts +0 -16
  81. package/dist/calendar.d.ts +0 -21
  82. package/dist/card.d.ts +0 -15
  83. package/dist/carousel.d.ts +0 -18
  84. package/dist/charts.d.ts +0 -26
  85. package/dist/checkbox.d.ts +0 -6
  86. package/dist/collapse.d.ts +0 -15
  87. package/dist/command-menu.d.ts +0 -12
  88. package/dist/command.d.ts +0 -89
  89. package/dist/components/alert-dialog.esm.js +0 -59
  90. package/dist/components/alert-dialog.esm.js.map +0 -1
  91. package/dist/components/alert-dialog.js.map +0 -1
  92. package/dist/components/alert.esm.js +0 -64
  93. package/dist/components/alert.esm.js.map +0 -1
  94. package/dist/components/alert.js.map +0 -1
  95. package/dist/components/avatar.esm.js +0 -42
  96. package/dist/components/avatar.esm.js.map +0 -1
  97. package/dist/components/avatar.js.map +0 -1
  98. package/dist/components/badge.esm.js +0 -27
  99. package/dist/components/badge.esm.js.map +0 -1
  100. package/dist/components/badge.js.map +0 -1
  101. package/dist/components/button.esm.js +0 -48
  102. package/dist/components/button.esm.js.map +0 -1
  103. package/dist/components/button.js.map +0 -1
  104. package/dist/components/calendar.esm.js +0 -5562
  105. package/dist/components/calendar.esm.js.map +0 -1
  106. package/dist/components/calendar.js.map +0 -1
  107. package/dist/components/card.esm.js +0 -62
  108. package/dist/components/card.esm.js.map +0 -1
  109. package/dist/components/card.js.map +0 -1
  110. package/dist/components/carousel.esm.js +0 -101
  111. package/dist/components/carousel.esm.js.map +0 -1
  112. package/dist/components/carousel.js.map +0 -1
  113. package/dist/components/charts.d.ts +0 -17
  114. package/dist/components/charts.esm.js +0 -48
  115. package/dist/components/charts.esm.js.map +0 -1
  116. package/dist/components/charts.js +0 -2
  117. package/dist/components/charts.js.map +0 -1
  118. package/dist/components/checkbox.esm.js +0 -32
  119. package/dist/components/checkbox.esm.js.map +0 -1
  120. package/dist/components/checkbox.js.map +0 -1
  121. package/dist/components/collapse.esm.js +0 -50
  122. package/dist/components/collapse.esm.js.map +0 -1
  123. package/dist/components/collapse.js.map +0 -1
  124. package/dist/components/command-menu.esm.js +0 -90
  125. package/dist/components/command-menu.esm.js.map +0 -1
  126. package/dist/components/command-menu.js.map +0 -1
  127. package/dist/components/command.esm.js +0 -425
  128. package/dist/components/command.esm.js.map +0 -1
  129. package/dist/components/command.js.map +0 -1
  130. package/dist/components/confirmation-modal.esm.js +0 -46
  131. package/dist/components/confirmation-modal.esm.js.map +0 -1
  132. package/dist/components/confirmation-modal.js.map +0 -1
  133. package/dist/components/context-menu.esm.js +0 -186
  134. package/dist/components/context-menu.esm.js.map +0 -1
  135. package/dist/components/context-menu.js.map +0 -1
  136. package/dist/components/dialog.esm.js +0 -122
  137. package/dist/components/dialog.esm.js.map +0 -1
  138. package/dist/components/dialog.js.map +0 -1
  139. package/dist/components/dropdown-menu.esm.js +0 -49
  140. package/dist/components/dropdown-menu.esm.js.map +0 -1
  141. package/dist/components/dropdown-menu.js.map +0 -1
  142. package/dist/components/dropzone.esm.js +0 -45
  143. package/dist/components/dropzone.esm.js.map +0 -1
  144. package/dist/components/dropzone.js.map +0 -1
  145. package/dist/components/image-cropper-modal.esm.js +0 -251
  146. package/dist/components/image-cropper-modal.esm.js.map +0 -1
  147. package/dist/components/image-cropper-modal.js.map +0 -1
  148. package/dist/components/image-cropper.esm.js +0 -131
  149. package/dist/components/image-cropper.esm.js.map +0 -1
  150. package/dist/components/image-cropper.js.map +0 -1
  151. package/dist/components/input.esm.js +0 -22
  152. package/dist/components/input.esm.js.map +0 -1
  153. package/dist/components/input.js.map +0 -1
  154. package/dist/components/label.esm.js +0 -20
  155. package/dist/components/label.esm.js.map +0 -1
  156. package/dist/components/label.js.map +0 -1
  157. package/dist/components/loader.esm.js +0 -70
  158. package/dist/components/loader.esm.js.map +0 -1
  159. package/dist/components/loader.js.map +0 -1
  160. package/dist/components/loading-placeholder.esm.js +0 -25
  161. package/dist/components/loading-placeholder.esm.js.map +0 -1
  162. package/dist/components/loading-placeholder.js.map +0 -1
  163. package/dist/components/markdown.d.ts +0 -2
  164. package/dist/components/markdown.esm.js +0 -12066
  165. package/dist/components/markdown.esm.js.map +0 -1
  166. package/dist/components/markdown.js +0 -18
  167. package/dist/components/markdown.js.map +0 -1
  168. package/dist/components/mention.esm.js +0 -154
  169. package/dist/components/mention.esm.js.map +0 -1
  170. package/dist/components/mention.js.map +0 -1
  171. package/dist/components/modal.esm.js +0 -136
  172. package/dist/components/modal.esm.js.map +0 -1
  173. package/dist/components/modal.js.map +0 -1
  174. package/dist/components/monaco-editor.d.ts +0 -2
  175. package/dist/components/monaco-editor.esm.js +0 -9
  176. package/dist/components/monaco-editor.esm.js.map +0 -1
  177. package/dist/components/monaco-editor.js +0 -2
  178. package/dist/components/monaco-editor.js.map +0 -1
  179. package/dist/components/notification.esm.js +0 -26
  180. package/dist/components/notification.esm.js.map +0 -1
  181. package/dist/components/notification.js.map +0 -1
  182. package/dist/components/popover.esm.js +0 -24
  183. package/dist/components/popover.esm.js.map +0 -1
  184. package/dist/components/popover.js.map +0 -1
  185. package/dist/components/progress.esm.js +0 -35
  186. package/dist/components/progress.esm.js.map +0 -1
  187. package/dist/components/progress.js.map +0 -1
  188. package/dist/components/radio-group.esm.js +0 -48
  189. package/dist/components/radio-group.esm.js.map +0 -1
  190. package/dist/components/radio-group.js.map +0 -1
  191. package/dist/components/scroll-area.esm.js +0 -47
  192. package/dist/components/scroll-area.esm.js.map +0 -1
  193. package/dist/components/scroll-area.js.map +0 -1
  194. package/dist/components/select.esm.js +0 -131
  195. package/dist/components/select.esm.js.map +0 -1
  196. package/dist/components/select.js.map +0 -1
  197. package/dist/components/selection-bar.esm.js +0 -54
  198. package/dist/components/selection-bar.esm.js.map +0 -1
  199. package/dist/components/selection-bar.js.map +0 -1
  200. package/dist/components/separator.esm.js +0 -25
  201. package/dist/components/separator.esm.js.map +0 -1
  202. package/dist/components/separator.js.map +0 -1
  203. package/dist/components/sheet.esm.js +0 -129
  204. package/dist/components/sheet.esm.js.map +0 -1
  205. package/dist/components/sheet.js.map +0 -1
  206. package/dist/components/skeleton.esm.js +0 -18
  207. package/dist/components/skeleton.esm.js.map +0 -1
  208. package/dist/components/skeleton.js.map +0 -1
  209. package/dist/components/slider.esm.js +0 -33
  210. package/dist/components/slider.esm.js.map +0 -1
  211. package/dist/components/slider.js.map +0 -1
  212. package/dist/components/stepper.d.ts +0 -2
  213. package/dist/components/stepper.esm.js +0 -7
  214. package/dist/components/stepper.esm.js.map +0 -1
  215. package/dist/components/stepper.js.map +0 -1
  216. package/dist/components/switch.esm.js +0 -36
  217. package/dist/components/switch.esm.js.map +0 -1
  218. package/dist/components/switch.js.map +0 -1
  219. package/dist/components/table-empty.esm.js +0 -23
  220. package/dist/components/table-empty.esm.js.map +0 -1
  221. package/dist/components/table-empty.js.map +0 -1
  222. package/dist/components/table-mobile.esm.js +0 -92
  223. package/dist/components/table-mobile.esm.js.map +0 -1
  224. package/dist/components/table-mobile.js.map +0 -1
  225. package/dist/components/table.esm.js +0 -157
  226. package/dist/components/table.esm.js.map +0 -1
  227. package/dist/components/table.js.map +0 -1
  228. package/dist/components/tabs.esm.js +0 -47
  229. package/dist/components/tabs.esm.js.map +0 -1
  230. package/dist/components/tabs.js.map +0 -1
  231. package/dist/components/terminal.esm.js +0 -50
  232. package/dist/components/terminal.esm.js.map +0 -1
  233. package/dist/components/terminal.js.map +0 -1
  234. package/dist/components/textarea.esm.js +0 -21
  235. package/dist/components/textarea.esm.js.map +0 -1
  236. package/dist/components/textarea.js.map +0 -1
  237. package/dist/components/tooltip.esm.js +0 -76
  238. package/dist/components/tooltip.esm.js.map +0 -1
  239. package/dist/components/tooltip.js.map +0 -1
  240. package/dist/components/use-toast.esm.js +0 -65
  241. package/dist/components/use-toast.esm.js.map +0 -1
  242. package/dist/components/use-toast.js.map +0 -1
  243. package/dist/confirmation-modal.d.ts +0 -16
  244. package/dist/context-menu.d.ts +0 -41
  245. package/dist/dialog.d.ts +0 -33
  246. package/dist/dropdown-menu.d.ts +0 -16
  247. package/dist/dropzone.d.ts +0 -16
  248. package/dist/image-cropper-modal.d.ts +0 -14
  249. package/dist/image-cropper.d.ts +0 -15
  250. package/dist/index-DACAHwoB.js +0 -35
  251. package/dist/index-DACAHwoB.js.map +0 -1
  252. package/dist/index-Deooizx8.cjs +0 -2
  253. package/dist/index-Deooizx8.cjs.map +0 -1
  254. package/dist/index.esm.js +0 -458
  255. package/dist/index.esm.js.map +0 -1
  256. package/dist/index.js.map +0 -1
  257. package/dist/input.d.ts +0 -8
  258. package/dist/jsx-runtime-BYECrxsp.cjs +0 -31
  259. package/dist/jsx-runtime-BYECrxsp.cjs.map +0 -1
  260. package/dist/jsx-runtime-DGlMoOmv.js +0 -631
  261. package/dist/jsx-runtime-DGlMoOmv.js.map +0 -1
  262. package/dist/label.d.ts +0 -6
  263. package/dist/lib/utils.esm.js +0 -5
  264. package/dist/lib/utils.esm.js.map +0 -1
  265. package/dist/lib/utils.js.map +0 -1
  266. package/dist/loader.d.ts +0 -14
  267. package/dist/loading-placeholder.d.ts +0 -12
  268. package/dist/markdown.d.ts +0 -122
  269. package/dist/mention.d.ts +0 -29
  270. package/dist/modal.d.ts +0 -28
  271. package/dist/monaco-editor.d.ts +0 -76
  272. package/dist/notification.d.ts +0 -9
  273. package/dist/popover.d.ts +0 -10
  274. package/dist/progress.d.ts +0 -6
  275. package/dist/radio-group.d.ts +0 -8
  276. package/dist/scroll-area.d.ts +0 -8
  277. package/dist/select.d.ts +0 -31
  278. package/dist/selection-bar.d.ts +0 -15
  279. package/dist/separator.d.ts +0 -6
  280. package/dist/sheet.d.ts +0 -17
  281. package/dist/skeleton.d.ts +0 -5
  282. package/dist/slider.d.ts +0 -6
  283. package/dist/stepper-modal-CPlBpxWy.cjs +0 -2
  284. package/dist/stepper-modal-CPlBpxWy.cjs.map +0 -1
  285. package/dist/stepper-modal-SYU9mbXs.js.map +0 -1
  286. package/dist/stepper.d.ts +0 -75
  287. package/dist/switch.d.ts +0 -6
  288. package/dist/table-empty.d.ts +0 -13
  289. package/dist/table-mobile.d.ts +0 -37
  290. package/dist/table.d.ts +0 -37
  291. package/dist/tabs.d.ts +0 -12
  292. package/dist/terminal.d.ts +0 -47
  293. package/dist/textarea.d.ts +0 -8
  294. package/dist/tooltip.d.ts +0 -12
  295. package/dist/use-toast.d.ts +0 -28
  296. package/dist/utils-DSKoFOjv.cjs +0 -2
  297. package/dist/utils-DSKoFOjv.cjs.map +0 -1
  298. package/dist/utils-qaFjX9_3.js +0 -2279
  299. package/dist/utils-qaFjX9_3.js.map +0 -1
  300. package/dist/utils.d.ts +0 -5
@@ -1,251 +0,0 @@
1
- import { j as s } from "../jsx-runtime-DGlMoOmv.js";
2
- import { useState as p, useRef as $, useCallback as h, useEffect as L } from "react";
3
- import { Button as R } from "./button.esm.js";
4
- import { Modal as W } from "./modal.esm.js";
5
- import { Label as q } from "./label.esm.js";
6
- import { RotateCcw as T, X as K, Check as F } from "lucide-react";
7
- function _({
8
- isOpen: m,
9
- onClose: b,
10
- imageSrc: u,
11
- onCrop: I,
12
- title: E = "Crop Your Image",
13
- outputSize: d = 200
14
- }) {
15
- const [t, x] = p({ x: 0, y: 0, size: 100 }), [z, v] = p(!1), [M, y] = p(!1), [N, P] = p({ x: 0, y: 0 }), [r, X] = p({ width: 0, height: 0 }), k = $(null), f = $(null), U = h(() => {
16
- if (f.current) {
17
- const e = f.current, i = 400, a = e.naturalWidth / e.naturalHeight;
18
- let n, o;
19
- a > 1 ? (n = i, o = i / a) : (o = i, n = i * a), X({ width: n, height: o });
20
- const l = Math.min(n, o) * 0.6;
21
- x({
22
- x: (n - l) / 2,
23
- y: (o - l) / 2,
24
- size: l
25
- });
26
- }
27
- }, []), w = h((e, i) => {
28
- e.preventDefault();
29
- const a = e.currentTarget.getBoundingClientRect(), n = e.clientX - a.left, o = e.clientY - a.top;
30
- if (i === "resize") {
31
- y(!0);
32
- const l = t.x + t.size / 2, g = t.y + t.size / 2, c = Math.sqrt((n - l) ** 2 + (o - g) ** 2);
33
- P({ x: c, y: 0 });
34
- } else
35
- v(!0), P({ x: n - t.x, y: o - t.y });
36
- }, [t]), A = h((e) => {
37
- if (!z && !M) return;
38
- const i = e.currentTarget.getBoundingClientRect(), a = e.clientX - i.left, n = e.clientY - i.top;
39
- if (M) {
40
- const o = t.x + t.size / 2, l = t.y + t.size / 2, g = Math.sqrt((a - o) ** 2 + (n - l) ** 2), c = Math.max(50, Math.min(Math.min(r.width, r.height), g * 2));
41
- x({
42
- x: Math.max(0, Math.min(r.width - c, o - c / 2)),
43
- y: Math.max(0, Math.min(r.height - c, l - c / 2)),
44
- size: c
45
- });
46
- } else if (z) {
47
- const o = a - N.x, l = n - N.y, g = r.width - t.size, c = r.height - t.size;
48
- x((D) => ({
49
- ...D,
50
- x: Math.max(0, Math.min(g, o)),
51
- y: Math.max(0, Math.min(c, l))
52
- }));
53
- }
54
- }, [z, M, N, r, t]), Y = h(() => {
55
- v(!1), y(!1);
56
- }, []), B = h(() => {
57
- if (r.width && r.height) {
58
- const e = Math.min(r.width, r.height) * 0.6;
59
- x({
60
- x: (r.width - e) / 2,
61
- y: (r.height - e) / 2,
62
- size: e
63
- });
64
- }
65
- }, [r]), H = h(() => {
66
- if (!k.current || !f.current) return;
67
- const e = k.current, i = e.getContext("2d");
68
- if (!i) return;
69
- const a = f.current;
70
- e.width = d, e.height = d;
71
- const n = a.naturalWidth / r.width, o = a.naturalHeight / r.height, l = t.x * n, g = t.y * o, c = t.size * Math.min(n, o);
72
- i.beginPath(), i.arc(d / 2, d / 2, d / 2, 0, Math.PI * 2), i.clip(), i.drawImage(
73
- a,
74
- l,
75
- g,
76
- c,
77
- c,
78
- 0,
79
- 0,
80
- d,
81
- d
82
- );
83
- const D = e.toDataURL("image/png");
84
- I(D), b();
85
- }, [t, r, I, b, d]), j = h(() => {
86
- v(!1), y(!1), x({ x: 0, y: 0, size: 100 }), b();
87
- }, [b]), C = h((e) => {
88
- e.key === "Escape" && m && (e.stopPropagation(), j());
89
- }, [m, j]);
90
- return L(() => {
91
- if (m)
92
- return document.addEventListener("keydown", C, !0), () => document.removeEventListener("keydown", C, !0);
93
- }, [m, C]), L(() => {
94
- m && u && (v(!1), y(!1), X({ width: 0, height: 0 }));
95
- }, [m, u]), u ? /* @__PURE__ */ s.jsx(
96
- W,
97
- {
98
- isOpen: m,
99
- onClose: j,
100
- title: E,
101
- size: "2xl",
102
- zIndexClassName: "z-[60]",
103
- footer: /* @__PURE__ */ s.jsxs("div", { className: "flex items-center justify-between w-full", children: [
104
- /* @__PURE__ */ s.jsxs(
105
- R,
106
- {
107
- variant: "ghost",
108
- size: "sm",
109
- onClick: B,
110
- className: "flex items-center gap-2",
111
- children: [
112
- /* @__PURE__ */ s.jsx(T, { className: "h-4 w-4" }),
113
- "Reset"
114
- ]
115
- }
116
- ),
117
- /* @__PURE__ */ s.jsxs("div", { className: "flex gap-3", children: [
118
- /* @__PURE__ */ s.jsxs(R, { variant: "outline", onClick: j, children: [
119
- /* @__PURE__ */ s.jsx(K, { className: "h-4 w-4 mr-2" }),
120
- "Cancel"
121
- ] }),
122
- /* @__PURE__ */ s.jsxs(R, { onClick: H, children: [
123
- /* @__PURE__ */ s.jsx(F, { className: "h-4 w-4 mr-2" }),
124
- "Crop Image"
125
- ] })
126
- ] })
127
- ] }),
128
- children: /* @__PURE__ */ s.jsxs("div", { className: "p-6", children: [
129
- /* @__PURE__ */ s.jsxs("div", { className: "space-y-6", children: [
130
- /* @__PURE__ */ s.jsx("div", { className: "text-center", children: /* @__PURE__ */ s.jsx("p", { className: "text-sm text-muted-foreground", children: "Drag the circle to move • Drag corners to resize • Click reset to center" }) }),
131
- /* @__PURE__ */ s.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ s.jsxs(
132
- "div",
133
- {
134
- className: "relative bg-gray-100 rounded-xl overflow-hidden select-none border",
135
- style: { width: r.width, height: r.height },
136
- onMouseMove: A,
137
- onMouseUp: Y,
138
- onMouseLeave: Y,
139
- children: [
140
- /* @__PURE__ */ s.jsx(
141
- "img",
142
- {
143
- ref: f,
144
- src: u,
145
- alt: "Crop preview",
146
- className: "block",
147
- style: { width: r.width, height: r.height },
148
- onLoad: U,
149
- draggable: !1
150
- }
151
- ),
152
- /* @__PURE__ */ s.jsxs(
153
- "div",
154
- {
155
- className: "absolute border-2 border-white rounded-full shadow-lg cursor-move",
156
- style: {
157
- left: t.x,
158
- top: t.y,
159
- width: t.size,
160
- height: t.size
161
- },
162
- onMouseDown: (e) => w(e, "move"),
163
- children: [
164
- /* @__PURE__ */ s.jsx("div", { className: "w-full h-full rounded-full border-2 border-primary border-dashed" }),
165
- /* @__PURE__ */ s.jsx(
166
- "div",
167
- {
168
- className: "absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-nw-resize -top-2.5 -right-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center",
169
- onMouseDown: (e) => {
170
- e.stopPropagation(), w(e, "resize");
171
- },
172
- children: /* @__PURE__ */ s.jsx("div", { className: "w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors" })
173
- }
174
- ),
175
- /* @__PURE__ */ s.jsx(
176
- "div",
177
- {
178
- className: "absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-ne-resize -bottom-2.5 -right-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center",
179
- onMouseDown: (e) => {
180
- e.stopPropagation(), w(e, "resize");
181
- },
182
- children: /* @__PURE__ */ s.jsx("div", { className: "w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors" })
183
- }
184
- ),
185
- /* @__PURE__ */ s.jsx(
186
- "div",
187
- {
188
- className: "absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-sw-resize -bottom-2.5 -left-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center",
189
- onMouseDown: (e) => {
190
- e.stopPropagation(), w(e, "resize");
191
- },
192
- children: /* @__PURE__ */ s.jsx("div", { className: "w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors" })
193
- }
194
- ),
195
- /* @__PURE__ */ s.jsx(
196
- "div",
197
- {
198
- className: "absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-se-resize -top-2.5 -left-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center",
199
- onMouseDown: (e) => {
200
- e.stopPropagation(), w(e, "resize");
201
- },
202
- children: /* @__PURE__ */ s.jsx("div", { className: "w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors" })
203
- }
204
- )
205
- ]
206
- }
207
- ),
208
- /* @__PURE__ */ s.jsx(
209
- "div",
210
- {
211
- className: "absolute inset-0 bg-black/50 pointer-events-none",
212
- style: {
213
- clipPath: `circle(${t.size / 2}px at ${t.x + t.size / 2}px ${t.y + t.size / 2}px)`
214
- }
215
- }
216
- )
217
- ]
218
- }
219
- ) }),
220
- /* @__PURE__ */ s.jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ s.jsxs("div", { className: "text-center", children: [
221
- /* @__PURE__ */ s.jsx(q, { className: "text-xs font-medium text-muted-foreground mb-2 block", children: "Preview" }),
222
- /* @__PURE__ */ s.jsx(
223
- "div",
224
- {
225
- className: "rounded-full border-2 border-border bg-background overflow-hidden mx-auto",
226
- style: { width: 80, height: 80 },
227
- children: /* @__PURE__ */ s.jsx(
228
- "div",
229
- {
230
- className: "w-full h-full bg-gray-100",
231
- style: {
232
- backgroundImage: `url(${u})`,
233
- backgroundSize: `${r.width / t.size * 80}px ${r.height / t.size * 80}px`,
234
- backgroundPosition: `-${t.x / t.size * 80}px -${t.y / t.size * 80}px`,
235
- backgroundRepeat: "no-repeat"
236
- }
237
- }
238
- )
239
- }
240
- )
241
- ] }) })
242
- ] }),
243
- /* @__PURE__ */ s.jsx("canvas", { ref: k, className: "hidden" })
244
- ] })
245
- }
246
- ) : null;
247
- }
248
- export {
249
- _ as ImageCropperModal
250
- };
251
- //# sourceMappingURL=image-cropper-modal.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-cropper-modal.esm.js","sources":["../../src/components/image-cropper-modal.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from 'react';\nimport { Button } from './button';\nimport { Modal } from './modal';\nimport { Label } from './label';\nimport { Check, X, RotateCcw } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ninterface CropArea {\n x: number;\n y: number;\n size: number;\n}\n\ninterface ImageCropperModalProps {\n isOpen: boolean;\n onClose: () => void;\n imageSrc: string | null;\n onCrop: (croppedImage: string) => void;\n title?: string;\n outputSize?: number;\n}\n\nexport function ImageCropperModal({ \n isOpen, \n onClose, \n imageSrc, \n onCrop,\n title = \"Crop Your Image\",\n outputSize = 200\n}: ImageCropperModalProps) {\n const [cropArea, setCropArea] = useState<CropArea>({ x: 0, y: 0, size: 100 });\n const [isDragging, setIsDragging] = useState(false);\n const [isResizing, setIsResizing] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [imageSize, setImageSize] = useState({ width: 0, height: 0 });\n \n const canvasRef = useRef<HTMLCanvasElement>(null);\n const imageRef = useRef<HTMLImageElement>(null);\n\n const handleImageLoad = useCallback(() => {\n if (imageRef.current) {\n const img = imageRef.current;\n const containerSize = 400; // Modal container size\n const imgAspect = img.naturalWidth / img.naturalHeight;\n \n let displayWidth, displayHeight;\n if (imgAspect > 1) {\n displayWidth = containerSize;\n displayHeight = containerSize / imgAspect;\n } else {\n displayHeight = containerSize;\n displayWidth = containerSize * imgAspect;\n }\n \n setImageSize({ width: displayWidth, height: displayHeight });\n \n // Center the crop area\n const cropSize = Math.min(displayWidth, displayHeight) * 0.6;\n setCropArea({\n x: (displayWidth - cropSize) / 2,\n y: (displayHeight - cropSize) / 2,\n size: cropSize\n });\n }\n }, []);\n\n const handleMouseDown = useCallback((e: React.MouseEvent, action: 'move' | 'resize') => {\n e.preventDefault();\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n \n if (action === 'resize') {\n setIsResizing(true);\n const centerX = cropArea.x + cropArea.size / 2;\n const centerY = cropArea.y + cropArea.size / 2;\n const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);\n setDragStart({ x: distance, y: 0 });\n } else {\n setIsDragging(true);\n setDragStart({ x: x - cropArea.x, y: y - cropArea.y });\n }\n }, [cropArea]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDragging && !isResizing) return;\n \n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n \n if (isResizing) {\n const centerX = cropArea.x + cropArea.size / 2;\n const centerY = cropArea.y + cropArea.size / 2;\n const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);\n const newSize = Math.max(50, Math.min(Math.min(imageSize.width, imageSize.height), distance * 2));\n \n // Keep crop area centered\n setCropArea({\n x: Math.max(0, Math.min(imageSize.width - newSize, centerX - newSize / 2)),\n y: Math.max(0, Math.min(imageSize.height - newSize, centerY - newSize / 2)),\n size: newSize\n });\n } else if (isDragging) {\n const newX = x - dragStart.x;\n const newY = y - dragStart.y;\n \n // Constrain crop area within image bounds\n const maxX = imageSize.width - cropArea.size;\n const maxY = imageSize.height - cropArea.size;\n \n setCropArea(prev => ({\n ...prev,\n x: Math.max(0, Math.min(maxX, newX)),\n y: Math.max(0, Math.min(maxY, newY))\n }));\n }\n }, [isDragging, isResizing, dragStart, imageSize, cropArea]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n }, []);\n\n const resetCrop = useCallback(() => {\n if (imageSize.width && imageSize.height) {\n const cropSize = Math.min(imageSize.width, imageSize.height) * 0.6;\n setCropArea({\n x: (imageSize.width - cropSize) / 2,\n y: (imageSize.height - cropSize) / 2,\n size: cropSize\n });\n }\n }, [imageSize]);\n\n const handleCrop = useCallback(() => {\n if (!canvasRef.current || !imageRef.current) return;\n \n const canvas = canvasRef.current;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n \n const img = imageRef.current;\n \n canvas.width = outputSize;\n canvas.height = outputSize;\n \n // Calculate crop area in original image coordinates\n const scaleX = img.naturalWidth / imageSize.width;\n const scaleY = img.naturalHeight / imageSize.height;\n \n const cropX = cropArea.x * scaleX;\n const cropY = cropArea.y * scaleY;\n const cropSize = cropArea.size * Math.min(scaleX, scaleY);\n \n // Create circular clip\n ctx.beginPath();\n ctx.arc(outputSize / 2, outputSize / 2, outputSize / 2, 0, Math.PI * 2);\n ctx.clip();\n \n // Draw cropped image\n ctx.drawImage(\n img,\n cropX, cropY, cropSize, cropSize,\n 0, 0, outputSize, outputSize\n );\n \n const croppedDataUrl = canvas.toDataURL('image/png');\n onCrop(croppedDataUrl);\n onClose();\n }, [cropArea, imageSize, onCrop, onClose, outputSize]);\n\n const handleClose = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n // Reset crop area to default when closing\n setCropArea({ x: 0, y: 0, size: 100 });\n onClose();\n }, [onClose]);\n\n // Prevent ESC key from bubbling to parent modal\n const handleKeyDown = useCallback((e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen) {\n e.stopPropagation();\n handleClose();\n }\n }, [isOpen, handleClose]);\n\n useEffect(() => {\n if (isOpen) {\n document.addEventListener('keydown', handleKeyDown, true); // Use capture phase\n return () => document.removeEventListener('keydown', handleKeyDown, true);\n }\n }, [isOpen, handleKeyDown]);\n\n // Reset crop area when image changes\n useEffect(() => {\n if (isOpen && imageSrc) {\n // Reset states when modal opens\n setIsDragging(false);\n setIsResizing(false);\n // Reset image size to trigger proper initialization\n setImageSize({ width: 0, height: 0 });\n }\n }, [isOpen, imageSrc]);\n\n if (!imageSrc) return null;\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n size=\"2xl\"\n zIndexClassName=\"z-[60]\"\n footer={\n <div className=\"flex items-center justify-between w-full\">\n <Button \n variant=\"ghost\" \n size=\"sm\"\n onClick={resetCrop}\n className=\"flex items-center gap-2\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n Reset\n </Button>\n <div className=\"flex gap-3\">\n <Button variant=\"outline\" onClick={handleClose}>\n <X className=\"h-4 w-4 mr-2\" />\n Cancel\n </Button>\n <Button onClick={handleCrop}>\n <Check className=\"h-4 w-4 mr-2\" />\n Crop Image\n </Button>\n </div>\n </div>\n }\n >\n <div className=\"p-6\">\n <div className=\"space-y-6\">\n <div className=\"text-center\">\n <p className=\"text-sm text-muted-foreground\">\n Drag the circle to move • Drag corners to resize • Click reset to center\n </p>\n </div>\n \n <div className=\"flex justify-center\">\n <div \n className=\"relative bg-gray-100 rounded-xl overflow-hidden select-none border\"\n style={{ width: imageSize.width, height: imageSize.height }}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n >\n <img\n ref={imageRef}\n src={imageSrc}\n alt=\"Crop preview\"\n className=\"block\"\n style={{ width: imageSize.width, height: imageSize.height }}\n onLoad={handleImageLoad}\n draggable={false}\n />\n \n {/* Crop area - draggable */}\n <div \n className=\"absolute border-2 border-white rounded-full shadow-lg cursor-move\"\n style={{\n left: cropArea.x,\n top: cropArea.y,\n width: cropArea.size,\n height: cropArea.size,\n }}\n onMouseDown={(e) => handleMouseDown(e, 'move')}\n >\n <div className=\"w-full h-full rounded-full border-2 border-primary border-dashed\" />\n \n {/* Resize handles */}\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-nw-resize -top-2.5 -right-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-ne-resize -bottom-2.5 -right-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-sw-resize -bottom-2.5 -left-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-se-resize -top-2.5 -left-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n </div>\n \n {/* Dark overlay */}\n <div \n className=\"absolute inset-0 bg-black/50 pointer-events-none\"\n style={{\n clipPath: `circle(${cropArea.size / 2}px at ${cropArea.x + cropArea.size / 2}px ${cropArea.y + cropArea.size / 2}px)`\n }}\n />\n </div>\n </div>\n\n {/* Preview */}\n <div className=\"flex justify-center\">\n <div className=\"text-center\">\n <Label className=\"text-xs font-medium text-muted-foreground mb-2 block\">Preview</Label>\n <div \n className=\"rounded-full border-2 border-border bg-background overflow-hidden mx-auto\"\n style={{ width: 80, height: 80 }}\n >\n <div\n className=\"w-full h-full bg-gray-100\"\n style={{\n backgroundImage: `url(${imageSrc})`,\n backgroundSize: `${(imageSize.width / cropArea.size) * 80}px ${(imageSize.height / cropArea.size) * 80}px`,\n backgroundPosition: `-${(cropArea.x / cropArea.size) * 80}px -${(cropArea.y / cropArea.size) * 80}px`,\n backgroundRepeat: 'no-repeat'\n }}\n />\n </div>\n </div>\n </div>\n </div>\n \n <canvas ref={canvasRef} className=\"hidden\" />\n </div>\n </Modal>\n );\n} "],"names":["ImageCropperModal","isOpen","onClose","imageSrc","onCrop","title","outputSize","cropArea","setCropArea","useState","isDragging","setIsDragging","isResizing","setIsResizing","dragStart","setDragStart","imageSize","setImageSize","canvasRef","useRef","imageRef","handleImageLoad","useCallback","img","containerSize","imgAspect","displayWidth","displayHeight","cropSize","handleMouseDown","action","rect","x","y","centerX","centerY","distance","handleMouseMove","newSize","newX","newY","maxX","maxY","prev","handleMouseUp","resetCrop","handleCrop","canvas","ctx","scaleX","scaleY","cropX","cropY","croppedDataUrl","handleClose","handleKeyDown","useEffect","jsx","Modal","jsxs","Button","RotateCcw","X","Check","Label"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-cropper-modal.js","sources":["../../src/components/image-cropper-modal.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback, useEffect } from 'react';\nimport { Button } from './button';\nimport { Modal } from './modal';\nimport { Label } from './label';\nimport { Check, X, RotateCcw } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ninterface CropArea {\n x: number;\n y: number;\n size: number;\n}\n\ninterface ImageCropperModalProps {\n isOpen: boolean;\n onClose: () => void;\n imageSrc: string | null;\n onCrop: (croppedImage: string) => void;\n title?: string;\n outputSize?: number;\n}\n\nexport function ImageCropperModal({ \n isOpen, \n onClose, \n imageSrc, \n onCrop,\n title = \"Crop Your Image\",\n outputSize = 200\n}: ImageCropperModalProps) {\n const [cropArea, setCropArea] = useState<CropArea>({ x: 0, y: 0, size: 100 });\n const [isDragging, setIsDragging] = useState(false);\n const [isResizing, setIsResizing] = useState(false);\n const [dragStart, setDragStart] = useState({ x: 0, y: 0 });\n const [imageSize, setImageSize] = useState({ width: 0, height: 0 });\n \n const canvasRef = useRef<HTMLCanvasElement>(null);\n const imageRef = useRef<HTMLImageElement>(null);\n\n const handleImageLoad = useCallback(() => {\n if (imageRef.current) {\n const img = imageRef.current;\n const containerSize = 400; // Modal container size\n const imgAspect = img.naturalWidth / img.naturalHeight;\n \n let displayWidth, displayHeight;\n if (imgAspect > 1) {\n displayWidth = containerSize;\n displayHeight = containerSize / imgAspect;\n } else {\n displayHeight = containerSize;\n displayWidth = containerSize * imgAspect;\n }\n \n setImageSize({ width: displayWidth, height: displayHeight });\n \n // Center the crop area\n const cropSize = Math.min(displayWidth, displayHeight) * 0.6;\n setCropArea({\n x: (displayWidth - cropSize) / 2,\n y: (displayHeight - cropSize) / 2,\n size: cropSize\n });\n }\n }, []);\n\n const handleMouseDown = useCallback((e: React.MouseEvent, action: 'move' | 'resize') => {\n e.preventDefault();\n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n \n if (action === 'resize') {\n setIsResizing(true);\n const centerX = cropArea.x + cropArea.size / 2;\n const centerY = cropArea.y + cropArea.size / 2;\n const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);\n setDragStart({ x: distance, y: 0 });\n } else {\n setIsDragging(true);\n setDragStart({ x: x - cropArea.x, y: y - cropArea.y });\n }\n }, [cropArea]);\n\n const handleMouseMove = useCallback((e: React.MouseEvent) => {\n if (!isDragging && !isResizing) return;\n \n const rect = e.currentTarget.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n \n if (isResizing) {\n const centerX = cropArea.x + cropArea.size / 2;\n const centerY = cropArea.y + cropArea.size / 2;\n const distance = Math.sqrt((x - centerX) ** 2 + (y - centerY) ** 2);\n const newSize = Math.max(50, Math.min(Math.min(imageSize.width, imageSize.height), distance * 2));\n \n // Keep crop area centered\n setCropArea({\n x: Math.max(0, Math.min(imageSize.width - newSize, centerX - newSize / 2)),\n y: Math.max(0, Math.min(imageSize.height - newSize, centerY - newSize / 2)),\n size: newSize\n });\n } else if (isDragging) {\n const newX = x - dragStart.x;\n const newY = y - dragStart.y;\n \n // Constrain crop area within image bounds\n const maxX = imageSize.width - cropArea.size;\n const maxY = imageSize.height - cropArea.size;\n \n setCropArea(prev => ({\n ...prev,\n x: Math.max(0, Math.min(maxX, newX)),\n y: Math.max(0, Math.min(maxY, newY))\n }));\n }\n }, [isDragging, isResizing, dragStart, imageSize, cropArea]);\n\n const handleMouseUp = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n }, []);\n\n const resetCrop = useCallback(() => {\n if (imageSize.width && imageSize.height) {\n const cropSize = Math.min(imageSize.width, imageSize.height) * 0.6;\n setCropArea({\n x: (imageSize.width - cropSize) / 2,\n y: (imageSize.height - cropSize) / 2,\n size: cropSize\n });\n }\n }, [imageSize]);\n\n const handleCrop = useCallback(() => {\n if (!canvasRef.current || !imageRef.current) return;\n \n const canvas = canvasRef.current;\n const ctx = canvas.getContext('2d');\n if (!ctx) return;\n \n const img = imageRef.current;\n \n canvas.width = outputSize;\n canvas.height = outputSize;\n \n // Calculate crop area in original image coordinates\n const scaleX = img.naturalWidth / imageSize.width;\n const scaleY = img.naturalHeight / imageSize.height;\n \n const cropX = cropArea.x * scaleX;\n const cropY = cropArea.y * scaleY;\n const cropSize = cropArea.size * Math.min(scaleX, scaleY);\n \n // Create circular clip\n ctx.beginPath();\n ctx.arc(outputSize / 2, outputSize / 2, outputSize / 2, 0, Math.PI * 2);\n ctx.clip();\n \n // Draw cropped image\n ctx.drawImage(\n img,\n cropX, cropY, cropSize, cropSize,\n 0, 0, outputSize, outputSize\n );\n \n const croppedDataUrl = canvas.toDataURL('image/png');\n onCrop(croppedDataUrl);\n onClose();\n }, [cropArea, imageSize, onCrop, onClose, outputSize]);\n\n const handleClose = useCallback(() => {\n setIsDragging(false);\n setIsResizing(false);\n // Reset crop area to default when closing\n setCropArea({ x: 0, y: 0, size: 100 });\n onClose();\n }, [onClose]);\n\n // Prevent ESC key from bubbling to parent modal\n const handleKeyDown = useCallback((e: KeyboardEvent) => {\n if (e.key === 'Escape' && isOpen) {\n e.stopPropagation();\n handleClose();\n }\n }, [isOpen, handleClose]);\n\n useEffect(() => {\n if (isOpen) {\n document.addEventListener('keydown', handleKeyDown, true); // Use capture phase\n return () => document.removeEventListener('keydown', handleKeyDown, true);\n }\n }, [isOpen, handleKeyDown]);\n\n // Reset crop area when image changes\n useEffect(() => {\n if (isOpen && imageSrc) {\n // Reset states when modal opens\n setIsDragging(false);\n setIsResizing(false);\n // Reset image size to trigger proper initialization\n setImageSize({ width: 0, height: 0 });\n }\n }, [isOpen, imageSrc]);\n\n if (!imageSrc) return null;\n\n return (\n <Modal\n isOpen={isOpen}\n onClose={handleClose}\n title={title}\n size=\"2xl\"\n zIndexClassName=\"z-[60]\"\n footer={\n <div className=\"flex items-center justify-between w-full\">\n <Button \n variant=\"ghost\" \n size=\"sm\"\n onClick={resetCrop}\n className=\"flex items-center gap-2\"\n >\n <RotateCcw className=\"h-4 w-4\" />\n Reset\n </Button>\n <div className=\"flex gap-3\">\n <Button variant=\"outline\" onClick={handleClose}>\n <X className=\"h-4 w-4 mr-2\" />\n Cancel\n </Button>\n <Button onClick={handleCrop}>\n <Check className=\"h-4 w-4 mr-2\" />\n Crop Image\n </Button>\n </div>\n </div>\n }\n >\n <div className=\"p-6\">\n <div className=\"space-y-6\">\n <div className=\"text-center\">\n <p className=\"text-sm text-muted-foreground\">\n Drag the circle to move • Drag corners to resize • Click reset to center\n </p>\n </div>\n \n <div className=\"flex justify-center\">\n <div \n className=\"relative bg-gray-100 rounded-xl overflow-hidden select-none border\"\n style={{ width: imageSize.width, height: imageSize.height }}\n onMouseMove={handleMouseMove}\n onMouseUp={handleMouseUp}\n onMouseLeave={handleMouseUp}\n >\n <img\n ref={imageRef}\n src={imageSrc}\n alt=\"Crop preview\"\n className=\"block\"\n style={{ width: imageSize.width, height: imageSize.height }}\n onLoad={handleImageLoad}\n draggable={false}\n />\n \n {/* Crop area - draggable */}\n <div \n className=\"absolute border-2 border-white rounded-full shadow-lg cursor-move\"\n style={{\n left: cropArea.x,\n top: cropArea.y,\n width: cropArea.size,\n height: cropArea.size,\n }}\n onMouseDown={(e) => handleMouseDown(e, 'move')}\n >\n <div className=\"w-full h-full rounded-full border-2 border-primary border-dashed\" />\n \n {/* Resize handles */}\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-nw-resize -top-2.5 -right-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-ne-resize -bottom-2.5 -right-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-sw-resize -bottom-2.5 -left-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n <div\n className=\"absolute w-5 h-5 bg-white border-2 border-primary rounded-full shadow-lg cursor-se-resize -top-2.5 -left-2.5 hover:bg-primary hover:border-white transition-colors flex items-center justify-center\"\n onMouseDown={(e) => {\n e.stopPropagation();\n handleMouseDown(e, 'resize');\n }}\n >\n <div className=\"w-1.5 h-1.5 bg-primary rounded-full hover:bg-white transition-colors\" />\n </div>\n </div>\n \n {/* Dark overlay */}\n <div \n className=\"absolute inset-0 bg-black/50 pointer-events-none\"\n style={{\n clipPath: `circle(${cropArea.size / 2}px at ${cropArea.x + cropArea.size / 2}px ${cropArea.y + cropArea.size / 2}px)`\n }}\n />\n </div>\n </div>\n\n {/* Preview */}\n <div className=\"flex justify-center\">\n <div className=\"text-center\">\n <Label className=\"text-xs font-medium text-muted-foreground mb-2 block\">Preview</Label>\n <div \n className=\"rounded-full border-2 border-border bg-background overflow-hidden mx-auto\"\n style={{ width: 80, height: 80 }}\n >\n <div\n className=\"w-full h-full bg-gray-100\"\n style={{\n backgroundImage: `url(${imageSrc})`,\n backgroundSize: `${(imageSize.width / cropArea.size) * 80}px ${(imageSize.height / cropArea.size) * 80}px`,\n backgroundPosition: `-${(cropArea.x / cropArea.size) * 80}px -${(cropArea.y / cropArea.size) * 80}px`,\n backgroundRepeat: 'no-repeat'\n }}\n />\n </div>\n </div>\n </div>\n </div>\n \n <canvas ref={canvasRef} className=\"hidden\" />\n </div>\n </Modal>\n );\n} "],"names":["ImageCropperModal","isOpen","onClose","imageSrc","onCrop","title","outputSize","cropArea","setCropArea","useState","isDragging","setIsDragging","isResizing","setIsResizing","dragStart","setDragStart","imageSize","setImageSize","canvasRef","useRef","imageRef","handleImageLoad","useCallback","img","containerSize","imgAspect","displayWidth","displayHeight","cropSize","handleMouseDown","action","rect","x","y","centerX","centerY","distance","handleMouseMove","newSize","newX","newY","maxX","maxY","prev","handleMouseUp","resetCrop","handleCrop","canvas","ctx","scaleX","scaleY","cropX","cropY","croppedDataUrl","handleClose","handleKeyDown","useEffect","jsx","Modal","jsxs","Button","RotateCcw","X","Check","Label"],"mappings":"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"}
@@ -1,131 +0,0 @@
1
- import { j as e } from "../jsx-runtime-DGlMoOmv.js";
2
- import { useState as u, useRef as I, useCallback as l } from "react";
3
- import { Button as f } from "./button.esm.js";
4
- import { RotateCw as M, X as S, Upload as E } from "lucide-react";
5
- import { ImageCropperModal as F } from "./image-cropper-modal.esm.js";
6
- import { c as O } from "../utils-qaFjX9_3.js";
7
- function L({
8
- value: i,
9
- onChange: t,
10
- size: a = 120,
11
- className: h,
12
- placeholder: x = "Upload Image",
13
- title: g = "Crop Your Image",
14
- outputSize: j = 200
15
- }) {
16
- const [b, c] = u(!1), [v, n] = u(null), s = I(null), C = l((r) => {
17
- var m;
18
- const o = (m = r.target.files) == null ? void 0 : m[0];
19
- if (o) {
20
- const d = new FileReader();
21
- d.onload = (R) => {
22
- var p;
23
- const k = (p = R.target) == null ? void 0 : p.result;
24
- n(k), c(!0);
25
- }, d.readAsDataURL(o);
26
- }
27
- r.target.value = "";
28
- }, []), N = l((r) => {
29
- t(r), n(null);
30
- }, [t]), w = l(() => {
31
- c(!1), n(null), s.current && (s.current.value = "");
32
- }, []), y = l(() => {
33
- t(null);
34
- }, [t]);
35
- return /* @__PURE__ */ e.jsxs(e.Fragment, { children: [
36
- /* @__PURE__ */ e.jsxs("div", { className: O("space-y-3", h), children: [
37
- i ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col items-center gap-3", children: [
38
- /* @__PURE__ */ e.jsx(
39
- "div",
40
- {
41
- className: "rounded-full border-2 border-border overflow-hidden bg-background",
42
- style: { width: a, height: a },
43
- children: /* @__PURE__ */ e.jsx(
44
- "img",
45
- {
46
- src: i,
47
- alt: "Agent avatar",
48
- className: "w-full h-full object-cover"
49
- }
50
- )
51
- }
52
- ),
53
- /* @__PURE__ */ e.jsxs("div", { className: "flex gap-2", children: [
54
- /* @__PURE__ */ e.jsxs(
55
- f,
56
- {
57
- variant: "outline",
58
- size: "sm",
59
- onClick: (r) => {
60
- var o;
61
- r.stopPropagation(), (o = s.current) == null || o.click();
62
- },
63
- children: [
64
- /* @__PURE__ */ e.jsx(M, { className: "h-3 w-3 mr-1" }),
65
- "Replace"
66
- ]
67
- }
68
- ),
69
- /* @__PURE__ */ e.jsxs(
70
- f,
71
- {
72
- variant: "outline",
73
- size: "sm",
74
- onClick: y,
75
- children: [
76
- /* @__PURE__ */ e.jsx(S, { className: "h-3 w-3 mr-1" }),
77
- "Remove"
78
- ]
79
- }
80
- )
81
- ] })
82
- ] }) : /* @__PURE__ */ e.jsxs(
83
- "button",
84
- {
85
- onClick: (r) => {
86
- var o;
87
- r.stopPropagation(), (o = s.current) == null || o.click();
88
- },
89
- className: "w-full border-2 border-dashed border-border/50 rounded-lg p-6 hover:border-primary/50 hover:bg-primary/2 transition-colors group",
90
- children: [
91
- /* @__PURE__ */ e.jsx(
92
- "div",
93
- {
94
- className: "mx-auto rounded-full bg-primary/10 flex items-center justify-center group-hover:bg-primary/15 transition-colors mb-3",
95
- style: { width: Math.min(a / 2, 60), height: Math.min(a / 2, 60) },
96
- children: /* @__PURE__ */ e.jsx(E, { className: "h-6 w-6 text-primary" })
97
- }
98
- ),
99
- /* @__PURE__ */ e.jsx("p", { className: "text-sm font-medium text-foreground mb-1", children: x }),
100
- /* @__PURE__ */ e.jsx("p", { className: "text-xs text-muted-foreground", children: "Click to browse" })
101
- ]
102
- }
103
- ),
104
- /* @__PURE__ */ e.jsx(
105
- "input",
106
- {
107
- ref: s,
108
- type: "file",
109
- accept: "image/*",
110
- onChange: C,
111
- className: "hidden"
112
- }
113
- )
114
- ] }),
115
- /* @__PURE__ */ e.jsx(
116
- F,
117
- {
118
- isOpen: b,
119
- onClose: w,
120
- imageSrc: v,
121
- onCrop: N,
122
- title: g,
123
- outputSize: j
124
- }
125
- )
126
- ] });
127
- }
128
- export {
129
- L as ImageCropper
130
- };
131
- //# sourceMappingURL=image-cropper.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-cropper.esm.js","sources":["../../src/components/image-cropper.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback } from 'react';\nimport { Button } from './button';\nimport { Upload, RotateCw, X } from 'lucide-react';\nimport { ImageCropperModal } from './image-cropper-modal';\nimport { cn } from '@/lib/utils';\n\ninterface ImageCropperProps {\n value?: string | null;\n onChange: (croppedImage: string | null) => void;\n size?: number;\n className?: string;\n placeholder?: string;\n title?: string;\n outputSize?: number;\n}\n\nexport function ImageCropper({ \n value, \n onChange, \n size = 120, \n className,\n placeholder = \"Upload Image\",\n title = \"Crop Your Image\",\n outputSize = 200\n}: ImageCropperProps) {\n const [isCropModalOpen, setIsCropModalOpen] = useState(false);\n const [imageToEdit, setImageToEdit] = useState<string | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = (event) => {\n const imageSrc = event.target?.result as string;\n setImageToEdit(imageSrc);\n setIsCropModalOpen(true);\n };\n reader.readAsDataURL(file);\n }\n // Reset the input value so the same file can be selected again\n e.target.value = '';\n }, []);\n\n const handleCrop = useCallback((croppedImage: string) => {\n onChange(croppedImage);\n setImageToEdit(null);\n }, [onChange]);\n\n const handleCloseCropModal = useCallback(() => {\n setIsCropModalOpen(false);\n setImageToEdit(null);\n // Reset file input to ensure it can be used again\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n }, []);\n\n const handleRemoveImage = useCallback(() => {\n onChange(null);\n }, [onChange]);\n\n return (\n <>\n <div className={cn(\"space-y-3\", className)}>\n {value ? (\n <div className=\"flex flex-col items-center gap-3\">\n <div \n className=\"rounded-full border-2 border-border overflow-hidden bg-background\"\n style={{ width: size, height: size }}\n >\n <img \n src={value} \n alt=\"Agent avatar\" \n className=\"w-full h-full object-cover\"\n />\n </div>\n \n <div className=\"flex gap-2\">\n <Button \n variant=\"outline\" \n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n fileInputRef.current?.click();\n }}\n >\n <RotateCw className=\"h-3 w-3 mr-1\" />\n Replace\n </Button>\n <Button \n variant=\"outline\" \n size=\"sm\"\n onClick={handleRemoveImage}\n >\n <X className=\"h-3 w-3 mr-1\" />\n Remove\n </Button>\n </div>\n </div>\n ) : (\n <button\n onClick={(e) => {\n e.stopPropagation();\n fileInputRef.current?.click();\n }}\n className=\"w-full border-2 border-dashed border-border/50 rounded-lg p-6 hover:border-primary/50 hover:bg-primary/2 transition-colors group\"\n >\n <div \n className=\"mx-auto rounded-full bg-primary/10 flex items-center justify-center group-hover:bg-primary/15 transition-colors mb-3\"\n style={{ width: Math.min(size / 2, 60), height: Math.min(size / 2, 60) }}\n >\n <Upload className=\"h-6 w-6 text-primary\" />\n </div>\n <p className=\"text-sm font-medium text-foreground mb-1\">{placeholder}</p>\n <p className=\"text-xs text-muted-foreground\">Click to browse</p>\n </button>\n )}\n \n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n className=\"hidden\"\n />\n </div>\n\n <ImageCropperModal\n isOpen={isCropModalOpen}\n onClose={handleCloseCropModal}\n imageSrc={imageToEdit}\n onCrop={handleCrop}\n title={title}\n outputSize={outputSize}\n />\n </>\n );\n} "],"names":["ImageCropper","value","onChange","size","className","placeholder","title","outputSize","isCropModalOpen","setIsCropModalOpen","useState","imageToEdit","setImageToEdit","fileInputRef","useRef","handleFileSelect","useCallback","e","file","_a","reader","event","imageSrc","handleCrop","croppedImage","handleCloseCropModal","handleRemoveImage","jsxs","Fragment","cn","jsx","Button","RotateCw","X","Upload","ImageCropperModal"],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"image-cropper.js","sources":["../../src/components/image-cropper.tsx"],"sourcesContent":["import React, { useState, useRef, useCallback } from 'react';\nimport { Button } from './button';\nimport { Upload, RotateCw, X } from 'lucide-react';\nimport { ImageCropperModal } from './image-cropper-modal';\nimport { cn } from '@/lib/utils';\n\ninterface ImageCropperProps {\n value?: string | null;\n onChange: (croppedImage: string | null) => void;\n size?: number;\n className?: string;\n placeholder?: string;\n title?: string;\n outputSize?: number;\n}\n\nexport function ImageCropper({ \n value, \n onChange, \n size = 120, \n className,\n placeholder = \"Upload Image\",\n title = \"Crop Your Image\",\n outputSize = 200\n}: ImageCropperProps) {\n const [isCropModalOpen, setIsCropModalOpen] = useState(false);\n const [imageToEdit, setImageToEdit] = useState<string | null>(null);\n const fileInputRef = useRef<HTMLInputElement>(null);\n\n const handleFileSelect = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {\n const file = e.target.files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = (event) => {\n const imageSrc = event.target?.result as string;\n setImageToEdit(imageSrc);\n setIsCropModalOpen(true);\n };\n reader.readAsDataURL(file);\n }\n // Reset the input value so the same file can be selected again\n e.target.value = '';\n }, []);\n\n const handleCrop = useCallback((croppedImage: string) => {\n onChange(croppedImage);\n setImageToEdit(null);\n }, [onChange]);\n\n const handleCloseCropModal = useCallback(() => {\n setIsCropModalOpen(false);\n setImageToEdit(null);\n // Reset file input to ensure it can be used again\n if (fileInputRef.current) {\n fileInputRef.current.value = '';\n }\n }, []);\n\n const handleRemoveImage = useCallback(() => {\n onChange(null);\n }, [onChange]);\n\n return (\n <>\n <div className={cn(\"space-y-3\", className)}>\n {value ? (\n <div className=\"flex flex-col items-center gap-3\">\n <div \n className=\"rounded-full border-2 border-border overflow-hidden bg-background\"\n style={{ width: size, height: size }}\n >\n <img \n src={value} \n alt=\"Agent avatar\" \n className=\"w-full h-full object-cover\"\n />\n </div>\n \n <div className=\"flex gap-2\">\n <Button \n variant=\"outline\" \n size=\"sm\"\n onClick={(e) => {\n e.stopPropagation();\n fileInputRef.current?.click();\n }}\n >\n <RotateCw className=\"h-3 w-3 mr-1\" />\n Replace\n </Button>\n <Button \n variant=\"outline\" \n size=\"sm\"\n onClick={handleRemoveImage}\n >\n <X className=\"h-3 w-3 mr-1\" />\n Remove\n </Button>\n </div>\n </div>\n ) : (\n <button\n onClick={(e) => {\n e.stopPropagation();\n fileInputRef.current?.click();\n }}\n className=\"w-full border-2 border-dashed border-border/50 rounded-lg p-6 hover:border-primary/50 hover:bg-primary/2 transition-colors group\"\n >\n <div \n className=\"mx-auto rounded-full bg-primary/10 flex items-center justify-center group-hover:bg-primary/15 transition-colors mb-3\"\n style={{ width: Math.min(size / 2, 60), height: Math.min(size / 2, 60) }}\n >\n <Upload className=\"h-6 w-6 text-primary\" />\n </div>\n <p className=\"text-sm font-medium text-foreground mb-1\">{placeholder}</p>\n <p className=\"text-xs text-muted-foreground\">Click to browse</p>\n </button>\n )}\n \n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"image/*\"\n onChange={handleFileSelect}\n className=\"hidden\"\n />\n </div>\n\n <ImageCropperModal\n isOpen={isCropModalOpen}\n onClose={handleCloseCropModal}\n imageSrc={imageToEdit}\n onCrop={handleCrop}\n title={title}\n outputSize={outputSize}\n />\n </>\n );\n} "],"names":["ImageCropper","value","onChange","size","className","placeholder","title","outputSize","isCropModalOpen","setIsCropModalOpen","useState","imageToEdit","setImageToEdit","fileInputRef","useRef","handleFileSelect","useCallback","e","file","_a","reader","event","imageSrc","handleCrop","croppedImage","handleCloseCropModal","handleRemoveImage","jsxs","Fragment","cn","jsx","Button","RotateCw","X","Upload","ImageCropperModal"],"mappings":"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"}
@@ -1,22 +0,0 @@
1
- import { j as t } from "../jsx-runtime-DGlMoOmv.js";
2
- import * as s from "react";
3
- import { c as n } from "../utils-qaFjX9_3.js";
4
- const f = s.forwardRef(
5
- ({ className: e, type: r, ...o }, i) => /* @__PURE__ */ t.jsx(
6
- "input",
7
- {
8
- type: r,
9
- className: n(
10
- "flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
11
- e
12
- ),
13
- ref: i,
14
- ...o
15
- }
16
- )
17
- );
18
- f.displayName = "Input";
19
- export {
20
- f as Input
21
- };
22
- //# sourceMappingURL=input.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"input.esm.js","sources":["../../src/components/input.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\nInput.displayName = \"Input\";\n\nexport { Input }; "],"names":["Input","React","className","type","props","ref","jsx","cn"],"mappings":";;;AAMA,MAAMA,IAAQC,EAAM;AAAA,EAClB,CAAC,EAAE,WAAAC,GAAW,MAAAC,GAAM,GAAGC,EAAA,GAASC,MAE5BC,gBAAAA,EAAAA;AAAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAAH;AAAA,MACA,WAAWI;AAAA,QACT;AAAA,QACAL;AAAA,MAAA;AAAA,MAEF,KAAAG;AAAA,MACC,GAAGD;AAAA,IAAA;AAAA,EAAA;AAIZ;AACAJ,EAAM,cAAc;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"input.js","sources":["../../src/components/input.tsx"],"sourcesContent":["import * as React from \"react\";\nimport { cn } from \"@/lib/utils\";\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-10 w-full rounded-md border border-border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50\",\n className\n )}\n ref={ref}\n {...props}\n />\n );\n }\n);\nInput.displayName = \"Input\";\n\nexport { Input }; "],"names":["Input","React","className","type","props","ref","jsx","cn"],"mappings":"+cAMMA,EAAQC,EAAM,WAClB,CAAC,CAAE,UAAAC,EAAW,KAAAC,EAAM,GAAGC,CAAA,EAASC,IAE5BC,EAAAA,kBAAAA,IAAC,QAAA,CACC,KAAAH,EACA,UAAWI,EAAAA,GACT,gWACAL,CAAA,EAEF,IAAAG,EACC,GAAGD,CAAA,CAAA,CAIZ,EACAJ,EAAM,YAAc"}
@@ -1,20 +0,0 @@
1
- import { j as t } from "../jsx-runtime-DGlMoOmv.js";
2
- import * as m from "react";
3
- import * as o from "@radix-ui/react-label";
4
- import { c as s } from "../utils-qaFjX9_3.js";
5
- const i = m.forwardRef(({ className: e, ...a }, r) => /* @__PURE__ */ t.jsx(
6
- o.Root,
7
- {
8
- ref: r,
9
- className: s(
10
- "text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70",
11
- e
12
- ),
13
- ...a
14
- }
15
- ));
16
- i.displayName = o.Root.displayName;
17
- export {
18
- i as Label
19
- };
20
- //# sourceMappingURL=label.esm.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"label.esm.js","sources":["../../src/components/label.tsx"],"sourcesContent":["import * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { cn } from \"@/lib/utils\"\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n className\n )}\n {...props}\n />\n))\nLabel.displayName = LabelPrimitive.Root.displayName\n\nexport { Label } "],"names":["Label","React","className","props","ref","jsx","LabelPrimitive","cn"],"mappings":";;;;AAIA,MAAMA,IAAQC,EAAM,WAGlB,CAAC,EAAE,WAAAC,GAAW,GAAGC,EAAA,GAASC,MAC1BC,gBAAAA,EAAAA;AAAAA,EAACC,EAAe;AAAA,EAAf;AAAA,IACC,KAAAF;AAAA,IACA,WAAWG;AAAA,MACT;AAAA,MACAL;AAAA,IAAA;AAAA,IAED,GAAGC;AAAA,EAAA;AACN,CACD;AACDH,EAAM,cAAcM,EAAe,KAAK;"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"label.js","sources":["../../src/components/label.tsx"],"sourcesContent":["import * as React from \"react\"\nimport * as LabelPrimitive from \"@radix-ui/react-label\"\nimport { cn } from \"@/lib/utils\"\n\nconst Label = React.forwardRef<\n React.ElementRef<typeof LabelPrimitive.Root>,\n React.ComponentPropsWithoutRef<typeof LabelPrimitive.Root>\n>(({ className, ...props }, ref) => (\n <LabelPrimitive.Root\n ref={ref}\n className={cn(\n \"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70\",\n className\n )}\n {...props}\n />\n))\nLabel.displayName = LabelPrimitive.Root.displayName\n\nexport { Label } "],"names":["Label","React","className","props","ref","jsx","LabelPrimitive","cn"],"mappings":"yfAIMA,EAAQC,EAAM,WAGlB,CAAC,CAAE,UAAAC,EAAW,GAAGC,CAAA,EAASC,IAC1BC,EAAAA,kBAAAA,IAACC,EAAe,KAAf,CACC,IAAAF,EACA,UAAWG,EAAAA,GACT,6FACAL,CAAA,EAED,GAAGC,CAAA,CACN,CACD,EACDH,EAAM,YAAcM,EAAe,KAAK"}