@kopexa/sight
Version:
Kopexa Sight Design System — React component library for GRC applications
844 lines (831 loc) • 28.2 kB
JavaScript
"use client";
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/components/file-upload/index.ts
var file_upload_exports = {};
__export(file_upload_exports, {
AvatarUpload: () => AvatarUpload
});
module.exports = __toCommonJS(file_upload_exports);
// src/components/file-upload/avatar-upload.tsx
var import_button = require("@kopexa/button");
var import_callout = require("@kopexa/callout");
var import_i18n4 = require("@kopexa/i18n");
var import_icons2 = require("@kopexa/icons");
var import_image_crop = require("@kopexa/image-crop");
var import_shared_utils3 = require("@kopexa/shared-utils");
var import_theme2 = require("@kopexa/theme");
var import_react2 = require("react");
// src/hooks/use-file-upload/index.ts
var import_i18n2 = require("@kopexa/i18n");
var import_shared_utils = require("@kopexa/shared-utils");
var import_react = require("react");
// src/hooks/use-file-upload/messages.ts
var import_i18n = require("@kopexa/i18n");
var messages = (0, import_i18n.defineMessages)({
file_exceeds_max: {
id: "use_file_upload.file_exceeds_max",
defaultMessage: `File "{name}" exceeds the maximum size of {max}.`,
description: "Shown when a single file is larger than allowed"
},
file_not_accepted: {
id: "use_file_upload.file_not_accepted",
defaultMessage: `File "{name}" is not an accepted file type.`,
description: "Shown when file type/extension doesn't match accept"
},
too_many_files: {
id: "file_upload.too_many_files",
defaultMessage: "You can only upload a maximum of {max} files.",
description: "Shown when maxFiles would be exceeded"
}
});
// src/hooks/use-file-upload/index.ts
var useFileUpload = (options = {}) => {
const {
maxFiles = Number.POSITIVE_INFINITY,
maxSize = Number.POSITIVE_INFINITY,
accept = "*",
multiple = false,
initialFiles = [],
onFilesChange,
onFilesAdded,
onError
} = options;
const t = (0, import_i18n2.useSafeIntl)();
const [state, setState] = (0, import_react.useState)({
files: initialFiles.map((file) => ({
file,
id: file.id,
preview: file.url
})),
isDragging: false,
errors: []
});
const inputRef = (0, import_react.useRef)(null);
const validateFile = (0, import_react.useCallback)(
(file) => {
if (file instanceof File) {
if (file.size > maxSize) {
return t.formatMessage(messages.file_exceeds_max, {
name: file.name,
max: (0, import_shared_utils.formatBytes)(maxSize)
});
}
} else {
if (file.size > maxSize) {
return t.formatMessage(messages.file_exceeds_max, {
name: file.name,
max: (0, import_shared_utils.formatBytes)(maxSize)
});
}
}
if (accept !== "*") {
const acceptedTypes = accept.split(",").map((type) => type.trim());
const fileType = file instanceof File ? file.type || "" : file.type;
const fileExtension = `.${file instanceof File ? file.name.split(".").pop() : file.name.split(".").pop()}`;
const isAccepted = acceptedTypes.some((type) => {
if (type.startsWith(".")) {
return fileExtension.toLowerCase() === type.toLowerCase();
}
if (type.endsWith("/*")) {
const baseType = type.split("/")[0];
return fileType.startsWith(`${baseType}/`);
}
return fileType === type;
});
if (!isAccepted) {
return t.formatMessage(messages.file_not_accepted, {
name: file instanceof File ? file.name : file.name
});
}
}
return null;
},
[accept, maxSize, t.formatMessage]
);
const createPreview = (0, import_react.useCallback)(
(file) => {
if (file instanceof File) {
return URL.createObjectURL(file);
}
return file.url;
},
[]
);
const generateUniqueId = (0, import_react.useCallback)((file) => {
if (file instanceof File) {
return `${file.name}-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`;
}
return file.id;
}, []);
const clearFiles = (0, import_react.useCallback)(() => {
setState((prev) => {
for (const file of prev.files) {
if (file.preview && file.file instanceof File && file.file.type.startsWith("image/")) {
URL.revokeObjectURL(file.preview);
}
}
if (inputRef.current) {
inputRef.current.value = "";
}
const newState = {
...prev,
files: [],
errors: []
};
onFilesChange == null ? void 0 : onFilesChange(newState.files);
return newState;
});
}, [onFilesChange]);
const addFiles = (0, import_react.useCallback)(
(newFiles) => {
if (!newFiles || newFiles.length === 0) return;
const newFilesArray = Array.from(newFiles);
const errors = [];
setState((prev) => ({ ...prev, errors: [] }));
if (!multiple) {
clearFiles();
}
if (multiple && maxFiles !== Number.POSITIVE_INFINITY && state.files.length + newFilesArray.length > maxFiles) {
errors.push(
t.formatMessage(messages.too_many_files, {
max: maxFiles
})
);
onError == null ? void 0 : onError(errors);
setState((prev) => ({ ...prev, errors }));
return;
}
const validFiles = [];
for (const file of newFilesArray) {
if (multiple) {
const isDuplicate = state.files.some(
(existingFile) => existingFile.file.name === file.name && existingFile.file.size === file.size
);
if (isDuplicate) {
return;
}
}
if (file.size > maxSize) {
errors.push(
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)}.`
);
continue;
}
const error = validateFile(file);
if (error) {
errors.push(error);
} else {
validFiles.push({
file,
id: generateUniqueId(file),
preview: createPreview(file)
});
}
}
if (validFiles.length > 0) {
onFilesAdded == null ? void 0 : onFilesAdded(validFiles);
setState((prev) => {
const newFiles2 = !multiple ? validFiles : [...prev.files, ...validFiles];
onFilesChange == null ? void 0 : onFilesChange(newFiles2);
return {
...prev,
files: newFiles2,
errors
};
});
} else if (errors.length > 0) {
onError == null ? void 0 : onError(errors);
setState((prev) => ({
...prev,
errors
}));
}
if (inputRef.current) {
inputRef.current.value = "";
}
},
[
onError,
state.files,
maxFiles,
multiple,
maxSize,
validateFile,
createPreview,
generateUniqueId,
clearFiles,
onFilesChange,
onFilesAdded,
t.formatMessage
]
);
const removeFile = (0, import_react.useCallback)(
(id) => {
setState((prev) => {
const fileToRemove = prev.files.find((file) => file.id === id);
if ((fileToRemove == null ? void 0 : fileToRemove.preview) && fileToRemove.file instanceof File && fileToRemove.file.type.startsWith("image/")) {
URL.revokeObjectURL(fileToRemove.preview);
}
const newFiles = prev.files.filter((file) => file.id !== id);
onFilesChange == null ? void 0 : onFilesChange(newFiles);
return {
...prev,
files: newFiles,
errors: []
};
});
},
[onFilesChange]
);
const clearErrors = (0, import_react.useCallback)(() => {
setState((prev) => ({
...prev,
errors: []
}));
}, []);
const handleDragEnter = (0, import_react.useCallback)((e) => {
e.preventDefault();
e.stopPropagation();
setState((prev) => ({ ...prev, isDragging: true }));
}, []);
const handleDragLeave = (0, import_react.useCallback)((e) => {
e.preventDefault();
e.stopPropagation();
if (e.currentTarget.contains(e.relatedTarget)) {
return;
}
setState((prev) => ({ ...prev, isDragging: false }));
}, []);
const handleDragOver = (0, import_react.useCallback)((e) => {
e.preventDefault();
e.stopPropagation();
}, []);
const handleDrop = (0, import_react.useCallback)(
(e) => {
var _a;
e.preventDefault();
e.stopPropagation();
setState((prev) => ({ ...prev, isDragging: false }));
if ((_a = inputRef.current) == null ? void 0 : _a.disabled) {
return;
}
if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
if (!multiple) {
const file = e.dataTransfer.files[0];
addFiles([file]);
} else {
addFiles(e.dataTransfer.files);
}
}
},
[addFiles, multiple]
);
const handleFileChange = (0, import_react.useCallback)(
(e) => {
if (e.target.files && e.target.files.length > 0) {
addFiles(e.target.files);
}
},
[addFiles]
);
const openFileDialog = (0, import_react.useCallback)(() => {
if (inputRef.current) {
inputRef.current.click();
}
}, []);
const getInputProps = (0, import_react.useCallback)(
(props = {}) => {
return {
...props,
type: "file",
onChange: handleFileChange,
accept: props.accept || accept,
multiple: props.multiple !== void 0 ? props.multiple : multiple,
ref: inputRef
};
},
[accept, multiple, handleFileChange]
);
return [
state,
{
addFiles,
removeFile,
clearFiles,
clearErrors,
handleDragEnter,
handleDragLeave,
handleDragOver,
handleDrop,
handleFileChange,
openFileDialog,
getInputProps
}
];
};
// src/components/dialog/dialog.tsx
var import_dialog = require("@base-ui/react/dialog");
var import_icons = require("@kopexa/icons");
var import_react_utils = require("@kopexa/react-utils");
var import_shared_utils2 = require("@kopexa/shared-utils");
var import_theme = require("@kopexa/theme");
var import_use_controllable_state = require("@kopexa/use-controllable-state");
var import_jsx_runtime = require("react/jsx-runtime");
var [DialogProvider, useDialogContext] = (0, import_react_utils.createContext)();
var DialogRoot = (props) => {
const {
open: openProp,
onOpenChange,
size,
radius,
placement,
scrollBehavior,
...restProps
} = props;
const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
value: openProp,
onChange: onOpenChange,
defaultValue: false
});
const styles = (0, import_theme.dialog)({ size, radius, placement, scrollBehavior });
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogProvider, { value: { styles, open, placement, size, radius }, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_dialog.Dialog.Root,
{
"data-slot": "dialog",
open,
onOpenChange: (open2) => setOpen(open2),
...restProps
}
) });
};
function DialogTrigger({ ...props }) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Trigger, { "data-slot": "dialog-trigger", ...props });
}
function DialogPortal({ ...props }) {
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dialog.Dialog.Portal, { "data-slot": "dialog-portal", ...props });
}
function DialogOverlay({ className, ...props }) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_dialog.Dialog.Backdrop,
{
"data-slot": "dialog-overlay",
className: (0, import_shared_utils2.cn)(styles.overlay(), className),
...props
}
);
}
function DialogContent({
className,
children,
showCloseButton = true,
...props
}) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(DialogPortal, { "data-slot": "dialog-portal", children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlay, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
import_dialog.Dialog.Popup,
{
"data-slot": "dialog-content",
className: (0, import_shared_utils2.cn)(styles.content(), className),
...props,
children: [
children,
showCloseButton && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
import_dialog.Dialog.Close,
{
"data-slot": "dialog-close",
className: styles.close(),
children: [
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_icons.CloseIcon, {}),
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "sr-only", children: "Close" })
]
}
)
]
}
)
] });
}
function DialogHeader({ className, ...props }) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
"data-slot": "dialog-header",
className: styles.header({ className }),
...props
}
);
}
function DialogFooter({ className, ...props }) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
"data-slot": "dialog-footer",
className: styles.footer({ className }),
...props
}
);
}
function DialogBody({ className, ...props }) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
"div",
{
"data-slot": "dialog-body",
className: styles.body({ className }),
...props
}
);
}
function DialogTitle({ className, ...props }) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_dialog.Dialog.Title,
{
"data-slot": "dialog-title",
className: (0, import_shared_utils2.cn)(styles.title(), className),
...props
}
);
}
function DialogDescription({
className,
...props
}) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_dialog.Dialog.Description,
{
"data-slot": "dialog-description",
className: (0, import_shared_utils2.cn)(styles.description(), className),
...props
}
);
}
function DialogCloseTrigger({
className,
...props
}) {
const { styles } = useDialogContext();
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
import_dialog.Dialog.Close,
{
"data-slot": "dialog-close-trigger",
className: (0, import_shared_utils2.cn)(styles.closeTrigger(), className),
...props
}
);
}
// src/components/dialog/index.ts
var Dialog = Object.assign(DialogRoot, {
Root: DialogRoot,
Body: DialogBody,
CloseTrigger: DialogCloseTrigger,
Content: DialogContent,
Description: DialogDescription,
Footer: DialogFooter,
Header: DialogHeader,
Overlay: DialogOverlay,
Portal: DialogPortal,
Title: DialogTitle,
Trigger: DialogTrigger
});
// src/components/file-upload/messages.ts
var import_i18n3 = require("@kopexa/i18n");
var messages2 = (0, import_i18n3.defineMessages)({
change_avatar: {
id: "file_upload.change_avatar",
defaultMessage: "Change Avatar",
description: "Label for changing the avatar image"
},
upload_avatar: {
id: "file_upload.upload_avatar",
defaultMessage: "Upload Avatar",
description: "Label for uploading a new avatar image"
},
remove_avatar: {
id: "file_upload.remove_avatar",
defaultMessage: "Remove Avatar",
description: "Label for removing the current avatar image"
},
avatar_uploaded: {
id: "file_upload.avatar_uploaded",
defaultMessage: "Avatar uploaded",
description: "Message displayed when the avatar is uploaded successfully"
},
accepted_file_types: {
id: "file_upload.accepted_file_types",
defaultMessage: "{types}{size, select, none {} other { up to {size}}}",
description: "Message indicating the accepted file types for upload"
},
cancel: {
id: "file_upload.cancel",
defaultMessage: "Cancel",
description: "Label for canceling the file upload"
},
apply_crop: {
id: "file_upload.apply_crop",
defaultMessage: "Apply",
description: "Label for applying the crop to the image"
}
});
// src/components/file-upload/utils/data-url-to-file.ts
async function dataUrlToFile(dataUrl, fileName, typeHint) {
const res = await fetch(dataUrl);
const blob = await res.blob();
const type = typeHint || blob.type || "image/png";
const ext = type.includes("jpeg") ? "jpg" : type.split("/")[1] || "png";
const safeName = fileName.replace(/\.[^.]+$/, "");
return new File([blob], `${safeName}-cropped.${ext}`, { type });
}
// src/components/file-upload/utils/format-accept-types.ts
var WILDCARD_GROUPS = {
"image/*": "common image formats",
"audio/*": "common audio formats",
"video/*": "common video formats",
"application/*": "common document formats"
};
var MIME_TO_LABEL = {
"image/png": "PNG",
"image/jpeg": "JPG",
"image/jpg": "JPG",
"application/pdf": "PDF",
"text/csv": "CSV",
"text/plain": "TXT"
};
var EXT_TO_LABEL = {
".png": "PNG",
".jpg": "JPG",
".jpeg": "JPG",
".pdf": "PDF",
".csv": "CSV",
".txt": "TXT"
};
function normalizeToken(token) {
return token.trim().toLowerCase();
}
function formatAcceptedTypes(accept) {
var _a, _b;
if (!accept || typeof accept !== "string") return "";
const tokens = accept.split(",").map(normalizeToken).filter(Boolean);
const labels = [];
for (const token of tokens) {
if (WILDCARD_GROUPS[token]) {
labels.push(WILDCARD_GROUPS[token]);
continue;
}
if (token.startsWith(".")) {
labels.push(
(_a = EXT_TO_LABEL[token]) != null ? _a : token.replace(/^\./, "").toUpperCase()
);
continue;
}
if (token.includes("/")) {
labels.push((_b = MIME_TO_LABEL[token]) != null ? _b : token.split("/")[1].toUpperCase());
}
}
const seen = /* @__PURE__ */ new Set();
return labels.filter((x) => {
if (seen.has(x)) return false;
seen.add(x);
return true;
}).join(", ");
}
// src/components/file-upload/utils/is-image-like.ts
function isImageLike(file) {
var _a, _b;
if ((_a = file.type) == null ? void 0 : _a.startsWith("image/")) return true;
const name = ((_b = file.name) == null ? void 0 : _b.toLowerCase()) || "";
return name.endsWith(".png") || name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".webp");
}
// src/components/file-upload/avatar-upload.tsx
var import_jsx_runtime2 = require("react/jsx-runtime");
var defaultMaxSize = 2 * 1024 * 1024;
var AvatarUpload = (props) => {
const {
maxSize = defaultMaxSize,
className,
onFileChange,
defaultAvatar,
orientation,
size,
shape,
accept = ".png,.jpg",
cropperEnabled = true,
cropAspect = 1,
cropMaxImageSize = defaultMaxSize,
onCroppedFile,
...rest
} = props;
const t = (0, import_i18n4.useSafeIntl)();
const [cropOpen, setCropOpen] = (0, import_react2.useState)(false);
const [cropSourceFile, setCropSourceFile] = (0, import_react2.useState)(null);
const pendingOriginalId = (0, import_react2.useRef)(null);
const [
{ files, isDragging, errors },
{
removeFile,
handleDragEnter,
handleDragLeave,
handleDragOver,
handleDrop,
openFileDialog,
getInputProps,
clearErrors,
addFiles
}
] = useFileUpload({
maxFiles: 1,
maxSize,
accept,
multiple: false,
onFilesChange: (files2) => {
onFileChange == null ? void 0 : onFileChange(files2[0] || null);
},
onFilesAdded: (added) => {
var _a;
if (!cropperEnabled) return;
const raw = (_a = added[0]) == null ? void 0 : _a.file;
if (raw instanceof File && isImageLike(raw)) {
pendingOriginalId.current = added[0].id;
setCropSourceFile(raw);
setCropOpen(true);
}
}
});
const currentFile = files[0];
const previewUrl = (currentFile == null ? void 0 : currentFile.preview) || defaultAvatar;
const handleRemove = () => {
if (currentFile) {
removeFile(currentFile.id);
clearErrors();
}
};
const styles = (0, import_theme2.avatarUpload)({
size,
shape,
orientation
});
const typesLabel = formatAcceptedTypes(accept);
const handleCropCancel = (0, import_react2.useCallback)(() => {
setCropOpen(false);
setCropSourceFile(null);
pendingOriginalId.current = null;
}, []);
const handleCropApply = (0, import_react2.useCallback)(
async (croppedDataUrl) => {
if (!croppedDataUrl || !cropSourceFile) {
handleCropCancel();
return;
}
const newFile = await dataUrlToFile(
croppedDataUrl,
cropSourceFile.name,
cropSourceFile.type
);
if (pendingOriginalId.current) {
removeFile(pendingOriginalId.current);
pendingOriginalId.current = null;
}
addFiles([newFile]);
onCroppedFile == null ? void 0 : onCroppedFile(newFile);
setCropOpen(false);
setCropSourceFile(null);
},
[cropSourceFile, addFiles, removeFile, onCroppedFile, handleCropCancel]
);
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
"div",
{
"data-slot": "avatar-upload",
className: styles.root({ className }),
...rest,
children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.previewAndText(), children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.previewContainer(), children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
"button",
{
type: "button",
"aria-label": previewUrl ? t.formatMessage(messages2.change_avatar) : t.formatMessage(messages2.upload_avatar),
"data-dragging": (0, import_shared_utils3.dataAttr)(isDragging),
"data-hasimage": (0, import_shared_utils3.dataAttr)(!!previewUrl),
className: styles.preview(),
onDragEnter: handleDragEnter,
onDragLeave: handleDragLeave,
onDragOver: handleDragOver,
onDrop: handleDrop,
onClick: openFileDialog,
children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { ...getInputProps(), className: "sr-only" }),
previewUrl ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
"img",
{
src: previewUrl,
alt: "Avatar",
className: styles.previewImg()
}
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: styles.placeholderWrapper(), children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons2.UserCircleIcon, { className: styles.placeholder() }) })
]
}
),
currentFile && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
import_button.IconButton,
{
variant: "outline",
color: "default",
onClick: handleRemove,
size: "sm",
className: styles.removeButton(),
"aria-label": t.formatMessage(messages2.remove_avatar),
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons2.CloseIcon, {})
}
)
] }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: styles.instructionsContainer(), children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: styles.instructions(), children: currentFile ? t.formatMessage(messages2.avatar_uploaded) : t.formatMessage(messages2.upload_avatar) }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: styles.acceptedFiles(), children: t.formatMessage(messages2.accepted_file_types, {
types: typesLabel || "-",
size: maxSize ? (0, import_shared_utils3.formatBytes)(maxSize) : "none"
}) })
] })
] }),
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())) })
]
}
),
cropperEnabled && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
Dialog.Root,
{
open: cropOpen,
onOpenChange: (v) => !v ? handleCropCancel() : null,
size: "2xl",
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Dialog.Content, { children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog.Header, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog.Title, { children: t.formatMessage(messages2.change_avatar) }) }),
cropSourceFile && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
import_image_crop.ImageCrop,
{
aspect: cropAspect,
file: cropSourceFile,
maxImageSize: cropMaxImageSize,
onCrop: handleCropApply,
children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog.Body, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_image_crop.ImageCropContent, { className: "max-w-md" }) }),
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Dialog.Footer, { children: [
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
Dialog.CloseTrigger,
{
render: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
import_button.Button,
{
variant: "ghost",
color: "default",
startContent: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_icons2.CloseIcon, {}),
children: t.formatMessage(messages2.cancel)
}
)
}
),
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
import_image_crop.ImageCropApply,
{
color: "primary",
variant: "solid",
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) })
}
)
] })
]
}
)
] })
}
)
] });
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
AvatarUpload
});