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