@kopexa/sight 17.12.0 → 17.13.0

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 (132) hide show
  1. package/dist/chunk-5LLYOCGQ.mjs +153 -0
  2. package/dist/chunk-6IAHC3UK.mjs +1 -0
  3. package/dist/chunk-6XUZNN3X.mjs +1 -0
  4. package/dist/chunk-7KISSD3Q.mjs +1 -0
  5. package/dist/chunk-BJ7QPNKW.mjs +242 -0
  6. package/dist/chunk-CZNF6WPR.mjs +33 -0
  7. package/dist/chunk-DU3OVIBY.mjs +16 -0
  8. package/dist/chunk-DWZQIPCX.mjs +301 -0
  9. package/dist/chunk-EAJ3DTJ3.mjs +59 -0
  10. package/dist/chunk-FBTSAODG.mjs +25 -0
  11. package/dist/chunk-G57FFIKP.mjs +48 -0
  12. package/dist/chunk-GR3VEF4M.mjs +1 -0
  13. package/dist/chunk-HISY6ZIK.mjs +1 -0
  14. package/dist/chunk-HUHVPC6T.mjs +17 -0
  15. package/dist/chunk-HVOS7SXF.mjs +15 -0
  16. package/dist/chunk-PKG2E3MX.mjs +1 -0
  17. package/dist/chunk-POVIOFVF.mjs +18 -0
  18. package/dist/chunk-RK7G2GYB.mjs +45 -0
  19. package/dist/chunk-SHETEVHO.mjs +178 -0
  20. package/dist/chunk-UWC3Z7SY.mjs +1 -0
  21. package/dist/chunk-UWQG4HGJ.mjs +13 -0
  22. package/dist/chunk-XL2RCXMY.mjs +26 -0
  23. package/dist/chunk-XPDEN2RV.mjs +1 -0
  24. package/dist/components/blankstate/blankstate.d.mts +14 -0
  25. package/dist/components/blankstate/blankstate.d.ts +14 -0
  26. package/dist/components/blankstate/blankstate.js +69 -0
  27. package/dist/components/blankstate/blankstate.mjs +7 -0
  28. package/dist/components/blankstate/index.d.mts +4 -0
  29. package/dist/components/blankstate/index.d.ts +4 -0
  30. package/dist/components/blankstate/index.js +71 -0
  31. package/dist/components/blankstate/index.mjs +8 -0
  32. package/dist/components/code/code.d.mts +9 -0
  33. package/dist/components/code/code.d.ts +9 -0
  34. package/dist/components/code/code.js +49 -0
  35. package/dist/components/code/code.mjs +7 -0
  36. package/dist/components/code/index.d.mts +4 -0
  37. package/dist/components/code/index.d.ts +4 -0
  38. package/dist/components/code/index.js +51 -0
  39. package/dist/components/code/index.mjs +8 -0
  40. package/dist/components/dialog/dialog.d.mts +44 -0
  41. package/dist/components/dialog/dialog.d.ts +44 -0
  42. package/dist/components/dialog/dialog.js +213 -0
  43. package/dist/components/dialog/dialog.mjs +31 -0
  44. package/dist/components/dialog/index.d.mts +22 -0
  45. package/dist/components/dialog/index.d.ts +22 -0
  46. package/dist/components/dialog/index.js +232 -0
  47. package/dist/components/dialog/index.mjs +35 -0
  48. package/dist/components/dialog/namespace.d.mts +5 -0
  49. package/dist/components/dialog/namespace.d.ts +5 -0
  50. package/dist/components/dialog/namespace.js +213 -0
  51. package/dist/components/dialog/namespace.mjs +29 -0
  52. package/dist/components/dialog/transition.d.mts +5 -0
  53. package/dist/components/dialog/transition.d.ts +5 -0
  54. package/dist/components/dialog/transition.js +132 -0
  55. package/dist/components/dialog/transition.mjs +106 -0
  56. package/dist/components/file-upload/avatar-upload.d.mts +54 -0
  57. package/dist/components/file-upload/avatar-upload.d.ts +54 -0
  58. package/dist/components/file-upload/avatar-upload.js +841 -0
  59. package/dist/components/file-upload/avatar-upload.mjs +15 -0
  60. package/dist/components/file-upload/index.d.mts +5 -0
  61. package/dist/components/file-upload/index.d.ts +5 -0
  62. package/dist/components/file-upload/index.js +843 -0
  63. package/dist/components/file-upload/index.mjs +16 -0
  64. package/dist/components/file-upload/messages.d.mts +39 -0
  65. package/dist/components/file-upload/messages.d.ts +39 -0
  66. package/dist/components/file-upload/messages.js +68 -0
  67. package/dist/components/file-upload/messages.mjs +7 -0
  68. package/dist/components/file-upload/utils/data-url-to-file.d.mts +3 -0
  69. package/dist/components/file-upload/utils/data-url-to-file.d.ts +3 -0
  70. package/dist/components/file-upload/utils/data-url-to-file.js +38 -0
  71. package/dist/components/file-upload/utils/data-url-to-file.mjs +7 -0
  72. package/dist/components/file-upload/utils/format-accept-types.d.mts +8 -0
  73. package/dist/components/file-upload/utils/format-accept-types.d.ts +8 -0
  74. package/dist/components/file-upload/utils/format-accept-types.js +82 -0
  75. package/dist/components/file-upload/utils/format-accept-types.mjs +7 -0
  76. package/dist/components/file-upload/utils/is-image-like.d.mts +3 -0
  77. package/dist/components/file-upload/utils/is-image-like.d.ts +3 -0
  78. package/dist/components/file-upload/utils/is-image-like.js +36 -0
  79. package/dist/components/file-upload/utils/is-image-like.mjs +7 -0
  80. package/dist/components/index.d.mts +67 -0
  81. package/dist/components/index.d.ts +67 -0
  82. package/dist/components/index.js +1137 -0
  83. package/dist/components/index.mjs +92 -0
  84. package/dist/components/skeleton/index.d.mts +5 -0
  85. package/dist/components/skeleton/index.d.ts +5 -0
  86. package/dist/components/skeleton/index.js +53 -0
  87. package/dist/components/skeleton/index.mjs +12 -0
  88. package/dist/components/skeleton/skeleton-avatar.d.mts +9 -0
  89. package/dist/components/skeleton/skeleton-avatar.d.ts +9 -0
  90. package/dist/components/skeleton/skeleton-avatar.js +51 -0
  91. package/dist/components/skeleton/skeleton-avatar.mjs +8 -0
  92. package/dist/components/skeleton/skeleton.d.mts +7 -0
  93. package/dist/components/skeleton/skeleton.d.ts +7 -0
  94. package/dist/components/skeleton/skeleton.js +39 -0
  95. package/dist/components/skeleton/skeleton.mjs +7 -0
  96. package/dist/components/stat/index.d.mts +4 -0
  97. package/dist/components/stat/index.d.ts +4 -0
  98. package/dist/components/stat/index.js +186 -0
  99. package/dist/components/stat/index.mjs +24 -0
  100. package/dist/components/stat/stat.d.mts +36 -0
  101. package/dist/components/stat/stat.d.ts +36 -0
  102. package/dist/components/stat/stat.js +185 -0
  103. package/dist/components/stat/stat.mjs +24 -0
  104. package/dist/components/textarea/index.d.mts +4 -0
  105. package/dist/components/textarea/index.d.ts +4 -0
  106. package/dist/components/textarea/index.js +42 -0
  107. package/dist/components/textarea/index.mjs +8 -0
  108. package/dist/components/textarea/textarea.d.mts +8 -0
  109. package/dist/components/textarea/textarea.d.ts +8 -0
  110. package/dist/components/textarea/textarea.js +40 -0
  111. package/dist/components/textarea/textarea.mjs +7 -0
  112. package/dist/hooks/index.d.mts +2 -0
  113. package/dist/hooks/index.d.ts +2 -0
  114. package/dist/hooks/index.js +341 -0
  115. package/dist/hooks/index.mjs +9 -0
  116. package/dist/hooks/use-file-upload/index.d.mts +47 -0
  117. package/dist/hooks/use-file-upload/index.d.ts +47 -0
  118. package/dist/hooks/use-file-upload/index.js +340 -0
  119. package/dist/hooks/use-file-upload/index.mjs +9 -0
  120. package/dist/hooks/use-file-upload/messages.d.mts +19 -0
  121. package/dist/hooks/use-file-upload/messages.d.ts +19 -0
  122. package/dist/hooks/use-file-upload/messages.js +48 -0
  123. package/dist/hooks/use-file-upload/messages.mjs +7 -0
  124. package/dist/index.d.mts +14 -8
  125. package/dist/index.d.ts +14 -8
  126. package/dist/index.js +1108 -32
  127. package/dist/index.mjs +82 -18
  128. package/dist/index.ts.backup.d.mts +14 -8
  129. package/dist/index.ts.backup.d.ts +14 -8
  130. package/dist/index.ts.backup.js +1108 -32
  131. package/dist/index.ts.backup.mjs +82 -18
  132. package/package.json +60 -64
@@ -0,0 +1,843 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/components/file-upload/index.ts
22
+ var file_upload_exports = {};
23
+ __export(file_upload_exports, {
24
+ AvatarUpload: () => AvatarUpload
25
+ });
26
+ module.exports = __toCommonJS(file_upload_exports);
27
+
28
+ // src/components/file-upload/avatar-upload.tsx
29
+ var import_button = require("@kopexa/button");
30
+ var import_callout = require("@kopexa/callout");
31
+ var import_i18n4 = require("@kopexa/i18n");
32
+ var import_icons2 = require("@kopexa/icons");
33
+ var import_image_crop = require("@kopexa/image-crop");
34
+ var import_shared_utils3 = require("@kopexa/shared-utils");
35
+ var import_theme2 = require("@kopexa/theme");
36
+ var import_react2 = require("react");
37
+
38
+ // src/hooks/use-file-upload/index.ts
39
+ var import_i18n2 = require("@kopexa/i18n");
40
+ var import_shared_utils = require("@kopexa/shared-utils");
41
+ var import_react = require("react");
42
+
43
+ // src/hooks/use-file-upload/messages.ts
44
+ var import_i18n = require("@kopexa/i18n");
45
+ var messages = (0, import_i18n.defineMessages)({
46
+ file_exceeds_max: {
47
+ id: "use_file_upload.file_exceeds_max",
48
+ defaultMessage: `File "{name}" exceeds the maximum size of {max}.`,
49
+ description: "Shown when a single file is larger than allowed"
50
+ },
51
+ file_not_accepted: {
52
+ id: "use_file_upload.file_not_accepted",
53
+ defaultMessage: `File "{name}" is not an accepted file type.`,
54
+ description: "Shown when file type/extension doesn't match accept"
55
+ },
56
+ too_many_files: {
57
+ id: "file_upload.too_many_files",
58
+ defaultMessage: "You can only upload a maximum of {max} files.",
59
+ description: "Shown when maxFiles would be exceeded"
60
+ }
61
+ });
62
+
63
+ // src/hooks/use-file-upload/index.ts
64
+ var useFileUpload = (options = {}) => {
65
+ const {
66
+ maxFiles = Number.POSITIVE_INFINITY,
67
+ maxSize = Number.POSITIVE_INFINITY,
68
+ accept = "*",
69
+ multiple = false,
70
+ initialFiles = [],
71
+ onFilesChange,
72
+ onFilesAdded,
73
+ onError
74
+ } = options;
75
+ const t = (0, import_i18n2.useSafeIntl)();
76
+ const [state, setState] = (0, import_react.useState)({
77
+ files: initialFiles.map((file) => ({
78
+ file,
79
+ id: file.id,
80
+ preview: file.url
81
+ })),
82
+ isDragging: false,
83
+ errors: []
84
+ });
85
+ const inputRef = (0, import_react.useRef)(null);
86
+ const validateFile = (0, import_react.useCallback)(
87
+ (file) => {
88
+ if (file instanceof File) {
89
+ if (file.size > maxSize) {
90
+ return t.formatMessage(messages.file_exceeds_max, {
91
+ name: file.name,
92
+ max: (0, import_shared_utils.formatBytes)(maxSize)
93
+ });
94
+ }
95
+ } else {
96
+ if (file.size > maxSize) {
97
+ return t.formatMessage(messages.file_exceeds_max, {
98
+ name: file.name,
99
+ max: (0, import_shared_utils.formatBytes)(maxSize)
100
+ });
101
+ }
102
+ }
103
+ if (accept !== "*") {
104
+ const acceptedTypes = accept.split(",").map((type) => type.trim());
105
+ const fileType = file instanceof File ? file.type || "" : file.type;
106
+ const fileExtension = `.${file instanceof File ? file.name.split(".").pop() : file.name.split(".").pop()}`;
107
+ const isAccepted = acceptedTypes.some((type) => {
108
+ if (type.startsWith(".")) {
109
+ return fileExtension.toLowerCase() === type.toLowerCase();
110
+ }
111
+ if (type.endsWith("/*")) {
112
+ const baseType = type.split("/")[0];
113
+ return fileType.startsWith(`${baseType}/`);
114
+ }
115
+ return fileType === type;
116
+ });
117
+ if (!isAccepted) {
118
+ return t.formatMessage(messages.file_not_accepted, {
119
+ name: file instanceof File ? file.name : file.name
120
+ });
121
+ }
122
+ }
123
+ return null;
124
+ },
125
+ [accept, maxSize, t.formatMessage]
126
+ );
127
+ const createPreview = (0, import_react.useCallback)(
128
+ (file) => {
129
+ if (file instanceof File) {
130
+ return URL.createObjectURL(file);
131
+ }
132
+ return file.url;
133
+ },
134
+ []
135
+ );
136
+ const generateUniqueId = (0, import_react.useCallback)((file) => {
137
+ if (file instanceof File) {
138
+ return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
139
+ }
140
+ return file.id;
141
+ }, []);
142
+ const clearFiles = (0, import_react.useCallback)(() => {
143
+ setState((prev) => {
144
+ for (const file of prev.files) {
145
+ if (file.preview && file.file instanceof File && file.file.type.startsWith("image/")) {
146
+ URL.revokeObjectURL(file.preview);
147
+ }
148
+ }
149
+ if (inputRef.current) {
150
+ inputRef.current.value = "";
151
+ }
152
+ const newState = {
153
+ ...prev,
154
+ files: [],
155
+ errors: []
156
+ };
157
+ onFilesChange == null ? void 0 : onFilesChange(newState.files);
158
+ return newState;
159
+ });
160
+ }, [onFilesChange]);
161
+ const addFiles = (0, import_react.useCallback)(
162
+ (newFiles) => {
163
+ if (!newFiles || newFiles.length === 0) return;
164
+ const newFilesArray = Array.from(newFiles);
165
+ const errors = [];
166
+ setState((prev) => ({ ...prev, errors: [] }));
167
+ if (!multiple) {
168
+ clearFiles();
169
+ }
170
+ if (multiple && maxFiles !== Number.POSITIVE_INFINITY && state.files.length + newFilesArray.length > maxFiles) {
171
+ errors.push(
172
+ t.formatMessage(messages.too_many_files, {
173
+ max: maxFiles
174
+ })
175
+ );
176
+ onError == null ? void 0 : onError(errors);
177
+ setState((prev) => ({ ...prev, errors }));
178
+ return;
179
+ }
180
+ const validFiles = [];
181
+ for (const file of newFilesArray) {
182
+ if (multiple) {
183
+ const isDuplicate = state.files.some(
184
+ (existingFile) => existingFile.file.name === file.name && existingFile.file.size === file.size
185
+ );
186
+ if (isDuplicate) {
187
+ return;
188
+ }
189
+ }
190
+ if (file.size > maxSize) {
191
+ errors.push(
192
+ multiple ? `Some files exceed the maximum size of ${(0, import_shared_utils.formatBytes)(maxSize)}.` : `File exceeds the maximum size of ${(0, import_shared_utils.formatBytes)(maxSize)}.`
193
+ );
194
+ continue;
195
+ }
196
+ const error = validateFile(file);
197
+ if (error) {
198
+ errors.push(error);
199
+ } else {
200
+ validFiles.push({
201
+ file,
202
+ id: generateUniqueId(file),
203
+ preview: createPreview(file)
204
+ });
205
+ }
206
+ }
207
+ if (validFiles.length > 0) {
208
+ onFilesAdded == null ? void 0 : onFilesAdded(validFiles);
209
+ setState((prev) => {
210
+ const newFiles2 = !multiple ? validFiles : [...prev.files, ...validFiles];
211
+ onFilesChange == null ? void 0 : onFilesChange(newFiles2);
212
+ return {
213
+ ...prev,
214
+ files: newFiles2,
215
+ errors
216
+ };
217
+ });
218
+ } else if (errors.length > 0) {
219
+ onError == null ? void 0 : onError(errors);
220
+ setState((prev) => ({
221
+ ...prev,
222
+ errors
223
+ }));
224
+ }
225
+ if (inputRef.current) {
226
+ inputRef.current.value = "";
227
+ }
228
+ },
229
+ [
230
+ onError,
231
+ state.files,
232
+ maxFiles,
233
+ multiple,
234
+ maxSize,
235
+ validateFile,
236
+ createPreview,
237
+ generateUniqueId,
238
+ clearFiles,
239
+ onFilesChange,
240
+ onFilesAdded,
241
+ t.formatMessage
242
+ ]
243
+ );
244
+ const removeFile = (0, import_react.useCallback)(
245
+ (id) => {
246
+ setState((prev) => {
247
+ const fileToRemove = prev.files.find((file) => file.id === id);
248
+ if ((fileToRemove == null ? void 0 : fileToRemove.preview) && fileToRemove.file instanceof File && fileToRemove.file.type.startsWith("image/")) {
249
+ URL.revokeObjectURL(fileToRemove.preview);
250
+ }
251
+ const newFiles = prev.files.filter((file) => file.id !== id);
252
+ onFilesChange == null ? void 0 : onFilesChange(newFiles);
253
+ return {
254
+ ...prev,
255
+ files: newFiles,
256
+ errors: []
257
+ };
258
+ });
259
+ },
260
+ [onFilesChange]
261
+ );
262
+ const clearErrors = (0, import_react.useCallback)(() => {
263
+ setState((prev) => ({
264
+ ...prev,
265
+ errors: []
266
+ }));
267
+ }, []);
268
+ const handleDragEnter = (0, import_react.useCallback)((e) => {
269
+ e.preventDefault();
270
+ e.stopPropagation();
271
+ setState((prev) => ({ ...prev, isDragging: true }));
272
+ }, []);
273
+ const handleDragLeave = (0, import_react.useCallback)((e) => {
274
+ e.preventDefault();
275
+ e.stopPropagation();
276
+ if (e.currentTarget.contains(e.relatedTarget)) {
277
+ return;
278
+ }
279
+ setState((prev) => ({ ...prev, isDragging: false }));
280
+ }, []);
281
+ const handleDragOver = (0, import_react.useCallback)((e) => {
282
+ e.preventDefault();
283
+ e.stopPropagation();
284
+ }, []);
285
+ const handleDrop = (0, import_react.useCallback)(
286
+ (e) => {
287
+ var _a;
288
+ e.preventDefault();
289
+ e.stopPropagation();
290
+ setState((prev) => ({ ...prev, isDragging: false }));
291
+ if ((_a = inputRef.current) == null ? void 0 : _a.disabled) {
292
+ return;
293
+ }
294
+ if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
295
+ if (!multiple) {
296
+ const file = e.dataTransfer.files[0];
297
+ addFiles([file]);
298
+ } else {
299
+ addFiles(e.dataTransfer.files);
300
+ }
301
+ }
302
+ },
303
+ [addFiles, multiple]
304
+ );
305
+ const handleFileChange = (0, import_react.useCallback)(
306
+ (e) => {
307
+ if (e.target.files && e.target.files.length > 0) {
308
+ addFiles(e.target.files);
309
+ }
310
+ },
311
+ [addFiles]
312
+ );
313
+ const openFileDialog = (0, import_react.useCallback)(() => {
314
+ if (inputRef.current) {
315
+ inputRef.current.click();
316
+ }
317
+ }, []);
318
+ const getInputProps = (0, import_react.useCallback)(
319
+ (props = {}) => {
320
+ return {
321
+ ...props,
322
+ type: "file",
323
+ onChange: handleFileChange,
324
+ accept: props.accept || accept,
325
+ multiple: props.multiple !== void 0 ? props.multiple : multiple,
326
+ ref: inputRef
327
+ };
328
+ },
329
+ [accept, multiple, handleFileChange]
330
+ );
331
+ return [
332
+ state,
333
+ {
334
+ addFiles,
335
+ removeFile,
336
+ clearFiles,
337
+ clearErrors,
338
+ handleDragEnter,
339
+ handleDragLeave,
340
+ handleDragOver,
341
+ handleDrop,
342
+ handleFileChange,
343
+ openFileDialog,
344
+ getInputProps
345
+ }
346
+ ];
347
+ };
348
+
349
+ // src/components/dialog/dialog.tsx
350
+ var import_dialog = require("@base-ui/react/dialog");
351
+ var import_icons = require("@kopexa/icons");
352
+ var import_react_utils = require("@kopexa/react-utils");
353
+ var import_shared_utils2 = require("@kopexa/shared-utils");
354
+ var import_theme = require("@kopexa/theme");
355
+ var import_use_controllable_state = require("@kopexa/use-controllable-state");
356
+ var import_jsx_runtime = require("react/jsx-runtime");
357
+ var [DialogProvider, useDialogContext] = (0, import_react_utils.createContext)();
358
+ var DialogRoot = (props) => {
359
+ const {
360
+ open: openProp,
361
+ onOpenChange,
362
+ size,
363
+ radius,
364
+ placement,
365
+ scrollBehavior,
366
+ ...restProps
367
+ } = props;
368
+ const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
369
+ value: openProp,
370
+ onChange: onOpenChange,
371
+ defaultValue: false
372
+ });
373
+ const styles = (0, import_theme.dialog)({ size, radius, placement, scrollBehavior });
374
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogProvider, { value: { styles, open, placement, size, radius }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
375
+ import_dialog.Dialog.Root,
376
+ {
377
+ "data-slot": "dialog",
378
+ open,
379
+ onOpenChange: (open2) => setOpen(open2),
380
+ ...restProps
381
+ }
382
+ ) });
383
+ };
384
+ function DialogTrigger({ ...props }) {
385
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Trigger, { "data-slot": "dialog-trigger", ...props });
386
+ }
387
+ function DialogPortal({ ...props }) {
388
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Portal, { "data-slot": "dialog-portal", ...props });
389
+ }
390
+ function DialogOverlay({ className, ...props }) {
391
+ const { styles } = useDialogContext();
392
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
393
+ import_dialog.Dialog.Backdrop,
394
+ {
395
+ "data-slot": "dialog-overlay",
396
+ className: (0, import_shared_utils2.cn)(styles.overlay(), className),
397
+ ...props
398
+ }
399
+ );
400
+ }
401
+ function DialogContent({
402
+ className,
403
+ children,
404
+ showCloseButton = true,
405
+ ...props
406
+ }) {
407
+ const { styles } = useDialogContext();
408
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [
409
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlay, {}),
410
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
411
+ import_dialog.Dialog.Popup,
412
+ {
413
+ "data-slot": "dialog-content",
414
+ className: (0, import_shared_utils2.cn)(styles.content(), className),
415
+ ...props,
416
+ children: [
417
+ children,
418
+ showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
419
+ import_dialog.Dialog.Close,
420
+ {
421
+ "data-slot": "dialog-close",
422
+ className: styles.close(),
423
+ children: [
424
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.CloseIcon, {}),
425
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "sr-only", children: "Close" })
426
+ ]
427
+ }
428
+ )
429
+ ]
430
+ }
431
+ )
432
+ ] });
433
+ }
434
+ function DialogHeader({ className, ...props }) {
435
+ const { styles } = useDialogContext();
436
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
437
+ "div",
438
+ {
439
+ "data-slot": "dialog-header",
440
+ className: styles.header({ className }),
441
+ ...props
442
+ }
443
+ );
444
+ }
445
+ function DialogFooter({ className, ...props }) {
446
+ const { styles } = useDialogContext();
447
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
448
+ "div",
449
+ {
450
+ "data-slot": "dialog-footer",
451
+ className: styles.footer({ className }),
452
+ ...props
453
+ }
454
+ );
455
+ }
456
+ function DialogBody({ className, ...props }) {
457
+ const { styles } = useDialogContext();
458
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
459
+ "div",
460
+ {
461
+ "data-slot": "dialog-body",
462
+ className: styles.body({ className }),
463
+ ...props
464
+ }
465
+ );
466
+ }
467
+ function DialogTitle({ className, ...props }) {
468
+ const { styles } = useDialogContext();
469
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
470
+ import_dialog.Dialog.Title,
471
+ {
472
+ "data-slot": "dialog-title",
473
+ className: (0, import_shared_utils2.cn)(styles.title(), className),
474
+ ...props
475
+ }
476
+ );
477
+ }
478
+ function DialogDescription({
479
+ className,
480
+ ...props
481
+ }) {
482
+ const { styles } = useDialogContext();
483
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
484
+ import_dialog.Dialog.Description,
485
+ {
486
+ "data-slot": "dialog-description",
487
+ className: (0, import_shared_utils2.cn)(styles.description(), className),
488
+ ...props
489
+ }
490
+ );
491
+ }
492
+ function DialogCloseTrigger({
493
+ className,
494
+ ...props
495
+ }) {
496
+ const { styles } = useDialogContext();
497
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
498
+ import_dialog.Dialog.Close,
499
+ {
500
+ "data-slot": "dialog-close-trigger",
501
+ className: (0, import_shared_utils2.cn)(styles.closeTrigger(), className),
502
+ ...props
503
+ }
504
+ );
505
+ }
506
+
507
+ // src/components/dialog/index.ts
508
+ var Dialog = Object.assign(DialogRoot, {
509
+ Root: DialogRoot,
510
+ Body: DialogBody,
511
+ CloseTrigger: DialogCloseTrigger,
512
+ Content: DialogContent,
513
+ Description: DialogDescription,
514
+ Footer: DialogFooter,
515
+ Header: DialogHeader,
516
+ Overlay: DialogOverlay,
517
+ Portal: DialogPortal,
518
+ Title: DialogTitle,
519
+ Trigger: DialogTrigger
520
+ });
521
+
522
+ // src/components/file-upload/messages.ts
523
+ var import_i18n3 = require("@kopexa/i18n");
524
+ var messages2 = (0, import_i18n3.defineMessages)({
525
+ change_avatar: {
526
+ id: "file_upload.change_avatar",
527
+ defaultMessage: "Change Avatar",
528
+ description: "Label for changing the avatar image"
529
+ },
530
+ upload_avatar: {
531
+ id: "file_upload.upload_avatar",
532
+ defaultMessage: "Upload Avatar",
533
+ description: "Label for uploading a new avatar image"
534
+ },
535
+ remove_avatar: {
536
+ id: "file_upload.remove_avatar",
537
+ defaultMessage: "Remove Avatar",
538
+ description: "Label for removing the current avatar image"
539
+ },
540
+ avatar_uploaded: {
541
+ id: "file_upload.avatar_uploaded",
542
+ defaultMessage: "Avatar uploaded",
543
+ description: "Message displayed when the avatar is uploaded successfully"
544
+ },
545
+ accepted_file_types: {
546
+ id: "file_upload.accepted_file_types",
547
+ defaultMessage: "{types}{size, select, none {} other { up to {size}}}",
548
+ description: "Message indicating the accepted file types for upload"
549
+ },
550
+ cancel: {
551
+ id: "file_upload.cancel",
552
+ defaultMessage: "Cancel",
553
+ description: "Label for canceling the file upload"
554
+ },
555
+ apply_crop: {
556
+ id: "file_upload.apply_crop",
557
+ defaultMessage: "Apply",
558
+ description: "Label for applying the crop to the image"
559
+ }
560
+ });
561
+
562
+ // src/components/file-upload/utils/data-url-to-file.ts
563
+ async function dataUrlToFile(dataUrl, fileName, typeHint) {
564
+ const res = await fetch(dataUrl);
565
+ const blob = await res.blob();
566
+ const type = typeHint || blob.type || "image/png";
567
+ const ext = type.includes("jpeg") ? "jpg" : type.split("/")[1] || "png";
568
+ const safeName = fileName.replace(/\.[^.]+$/, "");
569
+ return new File([blob], `${safeName}-cropped.${ext}`, { type });
570
+ }
571
+
572
+ // src/components/file-upload/utils/format-accept-types.ts
573
+ var WILDCARD_GROUPS = {
574
+ "image/*": "common image formats",
575
+ "audio/*": "common audio formats",
576
+ "video/*": "common video formats",
577
+ "application/*": "common document formats"
578
+ };
579
+ var MIME_TO_LABEL = {
580
+ "image/png": "PNG",
581
+ "image/jpeg": "JPG",
582
+ "image/jpg": "JPG",
583
+ "application/pdf": "PDF",
584
+ "text/csv": "CSV",
585
+ "text/plain": "TXT"
586
+ };
587
+ var EXT_TO_LABEL = {
588
+ ".png": "PNG",
589
+ ".jpg": "JPG",
590
+ ".jpeg": "JPG",
591
+ ".pdf": "PDF",
592
+ ".csv": "CSV",
593
+ ".txt": "TXT"
594
+ };
595
+ function normalizeToken(token) {
596
+ return token.trim().toLowerCase();
597
+ }
598
+ function formatAcceptedTypes(accept) {
599
+ var _a, _b;
600
+ if (!accept || typeof accept !== "string") return "";
601
+ const tokens = accept.split(",").map(normalizeToken).filter(Boolean);
602
+ const labels = [];
603
+ for (const token of tokens) {
604
+ if (WILDCARD_GROUPS[token]) {
605
+ labels.push(WILDCARD_GROUPS[token]);
606
+ continue;
607
+ }
608
+ if (token.startsWith(".")) {
609
+ labels.push(
610
+ (_a = EXT_TO_LABEL[token]) != null ? _a : token.replace(/^\./, "").toUpperCase()
611
+ );
612
+ continue;
613
+ }
614
+ if (token.includes("/")) {
615
+ labels.push((_b = MIME_TO_LABEL[token]) != null ? _b : token.split("/")[1].toUpperCase());
616
+ }
617
+ }
618
+ const seen = /* @__PURE__ */ new Set();
619
+ return labels.filter((x) => {
620
+ if (seen.has(x)) return false;
621
+ seen.add(x);
622
+ return true;
623
+ }).join(", ");
624
+ }
625
+
626
+ // src/components/file-upload/utils/is-image-like.ts
627
+ function isImageLike(file) {
628
+ var _a, _b;
629
+ if ((_a = file.type) == null ? void 0 : _a.startsWith("image/")) return true;
630
+ const name = ((_b = file.name) == null ? void 0 : _b.toLowerCase()) || "";
631
+ return name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".webp");
632
+ }
633
+
634
+ // src/components/file-upload/avatar-upload.tsx
635
+ var import_jsx_runtime2 = require("react/jsx-runtime");
636
+ var defaultMaxSize = 2 * 1024 * 1024;
637
+ var AvatarUpload = (props) => {
638
+ const {
639
+ maxSize = defaultMaxSize,
640
+ className,
641
+ onFileChange,
642
+ defaultAvatar,
643
+ orientation,
644
+ size,
645
+ shape,
646
+ accept = ".png,.jpg",
647
+ cropperEnabled = true,
648
+ cropAspect = 1,
649
+ cropMaxImageSize = defaultMaxSize,
650
+ onCroppedFile,
651
+ ...rest
652
+ } = props;
653
+ const t = (0, import_i18n4.useSafeIntl)();
654
+ const [cropOpen, setCropOpen] = (0, import_react2.useState)(false);
655
+ const [cropSourceFile, setCropSourceFile] = (0, import_react2.useState)(null);
656
+ const pendingOriginalId = (0, import_react2.useRef)(null);
657
+ const [
658
+ { files, isDragging, errors },
659
+ {
660
+ removeFile,
661
+ handleDragEnter,
662
+ handleDragLeave,
663
+ handleDragOver,
664
+ handleDrop,
665
+ openFileDialog,
666
+ getInputProps,
667
+ clearErrors,
668
+ addFiles
669
+ }
670
+ ] = useFileUpload({
671
+ maxFiles: 1,
672
+ maxSize,
673
+ accept,
674
+ multiple: false,
675
+ onFilesChange: (files2) => {
676
+ onFileChange == null ? void 0 : onFileChange(files2[0] || null);
677
+ },
678
+ onFilesAdded: (added) => {
679
+ var _a;
680
+ if (!cropperEnabled) return;
681
+ const raw = (_a = added[0]) == null ? void 0 : _a.file;
682
+ if (raw instanceof File && isImageLike(raw)) {
683
+ pendingOriginalId.current = added[0].id;
684
+ setCropSourceFile(raw);
685
+ setCropOpen(true);
686
+ }
687
+ }
688
+ });
689
+ const currentFile = files[0];
690
+ const previewUrl = (currentFile == null ? void 0 : currentFile.preview) || defaultAvatar;
691
+ const handleRemove = () => {
692
+ if (currentFile) {
693
+ removeFile(currentFile.id);
694
+ clearErrors();
695
+ }
696
+ };
697
+ const styles = (0, import_theme2.avatarUpload)({
698
+ size,
699
+ shape,
700
+ orientation
701
+ });
702
+ const typesLabel = formatAcceptedTypes(accept);
703
+ const handleCropCancel = (0, import_react2.useCallback)(() => {
704
+ setCropOpen(false);
705
+ setCropSourceFile(null);
706
+ pendingOriginalId.current = null;
707
+ }, []);
708
+ const handleCropApply = (0, import_react2.useCallback)(
709
+ async (croppedDataUrl) => {
710
+ if (!croppedDataUrl || !cropSourceFile) {
711
+ handleCropCancel();
712
+ return;
713
+ }
714
+ const newFile = await dataUrlToFile(
715
+ croppedDataUrl,
716
+ cropSourceFile.name,
717
+ cropSourceFile.type
718
+ );
719
+ if (pendingOriginalId.current) {
720
+ removeFile(pendingOriginalId.current);
721
+ pendingOriginalId.current = null;
722
+ }
723
+ addFiles([newFile]);
724
+ onCroppedFile == null ? void 0 : onCroppedFile(newFile);
725
+ setCropOpen(false);
726
+ setCropSourceFile(null);
727
+ },
728
+ [cropSourceFile, addFiles, removeFile, onCroppedFile, handleCropCancel]
729
+ );
730
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
731
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
732
+ "div",
733
+ {
734
+ "data-slot": "avatar-upload",
735
+ className: styles.root({ className }),
736
+ ...rest,
737
+ children: [
738
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.previewAndText(), children: [
739
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.previewContainer(), children: [
740
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
741
+ "button",
742
+ {
743
+ type: "button",
744
+ "aria-label": previewUrl ? t.formatMessage(messages2.change_avatar) : t.formatMessage(messages2.upload_avatar),
745
+ "data-dragging": (0, import_shared_utils3.dataAttr)(isDragging),
746
+ "data-hasimage": (0, import_shared_utils3.dataAttr)(!!previewUrl),
747
+ className: styles.preview(),
748
+ onDragEnter: handleDragEnter,
749
+ onDragLeave: handleDragLeave,
750
+ onDragOver: handleDragOver,
751
+ onDrop: handleDrop,
752
+ onClick: openFileDialog,
753
+ children: [
754
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { ...getInputProps(), className: "sr-only" }),
755
+ previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
756
+ "img",
757
+ {
758
+ src: previewUrl,
759
+ alt: "Avatar",
760
+ className: styles.previewImg()
761
+ }
762
+ ) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: styles.placeholderWrapper(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons2.UserCircleIcon, { className: styles.placeholder() }) })
763
+ ]
764
+ }
765
+ ),
766
+ currentFile && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
767
+ import_button.IconButton,
768
+ {
769
+ variant: "outline",
770
+ color: "default",
771
+ onClick: handleRemove,
772
+ size: "sm",
773
+ className: styles.removeButton(),
774
+ "aria-label": t.formatMessage(messages2.remove_avatar),
775
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons2.CloseIcon, {})
776
+ }
777
+ )
778
+ ] }),
779
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.instructionsContainer(), children: [
780
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: styles.instructions(), children: currentFile ? t.formatMessage(messages2.avatar_uploaded) : t.formatMessage(messages2.upload_avatar) }),
781
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: styles.acceptedFiles(), children: t.formatMessage(messages2.accepted_file_types, {
782
+ types: typesLabel || "-",
783
+ size: maxSize ? (0, import_shared_utils3.formatBytes)(maxSize) : "none"
784
+ }) })
785
+ ] })
786
+ ] }),
787
+ errors.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_callout.Callout, { variant: "destructive", children: errors.map((error, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: styles.errorItem(), children: error }, index.toString())) })
788
+ ]
789
+ }
790
+ ),
791
+ cropperEnabled && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
792
+ Dialog.Root,
793
+ {
794
+ open: cropOpen,
795
+ onOpenChange: (v) => !v ? handleCropCancel() : null,
796
+ size: "2xl",
797
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Dialog.Content, { children: [
798
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog.Title, { children: t.formatMessage(messages2.change_avatar) }) }),
799
+ cropSourceFile && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
800
+ import_image_crop.ImageCrop,
801
+ {
802
+ aspect: cropAspect,
803
+ file: cropSourceFile,
804
+ maxImageSize: cropMaxImageSize,
805
+ onCrop: handleCropApply,
806
+ children: [
807
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_image_crop.ImageCropContent, { className: "max-w-md" }) }),
808
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Dialog.Footer, { children: [
809
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
810
+ Dialog.CloseTrigger,
811
+ {
812
+ render: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
813
+ import_button.Button,
814
+ {
815
+ variant: "ghost",
816
+ color: "default",
817
+ startContent: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons2.CloseIcon, {}),
818
+ children: t.formatMessage(messages2.cancel)
819
+ }
820
+ )
821
+ }
822
+ ),
823
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
824
+ import_image_crop.ImageCropApply,
825
+ {
826
+ color: "primary",
827
+ variant: "solid",
828
+ render: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_button.Button, { startContent: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons2.CropIcon, {}), children: t.formatMessage(messages2.apply_crop) })
829
+ }
830
+ )
831
+ ] })
832
+ ]
833
+ }
834
+ )
835
+ ] })
836
+ }
837
+ )
838
+ ] });
839
+ };
840
+ // Annotate the CommonJS export names for ESM import in node:
841
+ 0 && (module.exports = {
842
+ AvatarUpload
843
+ });