@lobehub/ui
Version:
Lobe UI is an open-source UI component library for building AIGC web apps
128 lines (127 loc) • 4.15 kB
JavaScript
"use client";
import FlexBasic_default from "../Flex/FlexBasic.mjs";
import Center from "../Flex/Center.mjs";
import Icon from "../Icon/Icon.mjs";
import Text from "../Text/Text.mjs";
import Button from "../base-ui/Button/Button.mjs";
import UploadDragger from "../base-ui/Upload/UploadDragger.mjs";
import Tag from "../base-ui/Tag/Tag.mjs";
import { useTranslation } from "../i18n/useTranslation.mjs";
import emojiPicker_default from "../i18n/resources/en/emojiPicker.mjs";
import { ToastHost, toast } from "../base-ui/Toast/imperative.mjs";
import { memo, useCallback, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { cssVar } from "antd-style";
import { ChevronLeftIcon, ImageUpIcon } from "lucide-react";
import AvatarEditor from "react-avatar-editor";
//#region src/EmojiPicker/AvatarUploader.tsx
const ACCEPTED_IMAGE_TYPES = /* @__PURE__ */ new Set([
"image/jpeg",
"image/png",
"image/gif",
"image/webp"
]);
const readAsDataURL = (file, onLoad) => {
const reader = new FileReader();
reader.readAsDataURL(file);
reader.addEventListener("load", () => {
onLoad(String(reader.result));
});
};
const AvatarUploader = memo(({ shape, onChange, texts, compressSize = 256, onUpload }) => {
const editor = useRef(null);
const [previewImage, setPreviewImage] = useState("");
const { t } = useTranslation(emojiPicker_default);
const fileTypeErrorText = texts?.fileTypeError ?? t("emojiPicker.fileTypeError");
const draggerDescText = texts?.draggerDesc ?? t("emojiPicker.draggerDesc");
const uploadBtnText = texts?.uploadBtn ?? t("emojiPicker.uploadBtn");
const handleFiles = useCallback(([file]) => {
if (!ACCEPTED_IMAGE_TYPES.has(file.type)) {
toast.error(fileTypeErrorText);
return;
}
readAsDataURL(file, setPreviewImage);
}, [fileTypeErrorText]);
const handleUpload = () => {
if (!editor.current) return;
const canvasScaled = editor.current.getImageScaledToCanvas();
onChange(canvasScaled.toDataURL());
if (!onUpload) return;
canvasScaled.toBlob((blob) => {
if (blob) onUpload(new File([blob], "avatar.webp", { type: "image/webp" }));
}, "image/webp", .95);
};
return /* @__PURE__ */ jsxs(FlexBasic_default, {
padding: 10,
style: { position: "relative" },
width: "100%",
children: [
!previewImage && /* @__PURE__ */ jsx(UploadDragger, {
maxCount: 1,
onFiles: handleFiles,
children: /* @__PURE__ */ jsxs(Center, {
gap: 16,
height: compressSize,
width: compressSize,
children: [
/* @__PURE__ */ jsx(Icon, {
color: cssVar.colorTextDescription,
icon: ImageUpIcon,
size: 48
}),
/* @__PURE__ */ jsx(Text, {
color: cssVar.colorTextSecondary,
children: draggerDescText
}),
/* @__PURE__ */ jsxs(Center, {
horizontal: true,
gap: 4,
children: [
/* @__PURE__ */ jsx(Tag, { children: "JPG" }),
/* @__PURE__ */ jsx(Tag, { children: "PNG" }),
/* @__PURE__ */ jsx(Tag, { children: "GIF" }),
/* @__PURE__ */ jsx(Tag, { children: "WEBP" })
]
})
]
})
}),
previewImage && /* @__PURE__ */ jsxs(Center, {
gap: 8,
style: { position: "relative" },
width: "100%",
children: [/* @__PURE__ */ jsx(AvatarEditor, {
border: 0,
borderRadius: shape === "square" ? void 0 : compressSize / 2,
height: compressSize,
image: previewImage,
ref: editor,
width: compressSize
}), /* @__PURE__ */ jsxs(FlexBasic_default, {
horizontal: true,
gap: 8,
style: { position: "relative" },
width: "100%",
children: [/* @__PURE__ */ jsx(Button, {
icon: ChevronLeftIcon,
style: { flex: "none" },
onClick: () => setPreviewImage("")
}), /* @__PURE__ */ jsx(Button, {
style: {
flex: 1,
fontWeight: 500
},
type: "primary",
onClick: handleUpload,
children: uploadBtnText
})]
})]
}),
/* @__PURE__ */ jsx(ToastHost, {})
]
});
});
AvatarUploader.displayName = "AvatarUploader";
//#endregion
export { AvatarUploader as default };
//# sourceMappingURL=AvatarUploader.mjs.map