This commit is contained in:
2025-12-02 16:30:46 +01:00
parent 979728e6c8
commit 0b7c70058d
31 changed files with 298 additions and 106 deletions
+88 -20
View File
@@ -11,6 +11,7 @@ import fileInputToBase64 from "../utils/form/fileInputToBase64";
import Row from "../layout/Row";
import Input from "./Input";
import Loading from "../elements/Loading";
import Tag from "../elements/Tag";
type FileInputUtils = {
clearFileInput?: () => void;
@@ -59,6 +60,7 @@ type ImageUploadProps = DetailedHTMLProps<
existingFile?: FileInputToBase64FunctionReturn;
existingFileUrl?: string;
icon?: ReactNode;
externalSetFileURL?: React.Dispatch<string | undefined>;
labelSpanProps?: ComponentProps<typeof Span>;
loading?: boolean;
multiple?: boolean;
@@ -86,6 +88,7 @@ export default function FileUpload({
multiple,
onClear,
changeHandler,
externalSetFileURL,
...props
}: ImageUploadProps) {
const [file, setFile] = React.useState<
@@ -97,6 +100,7 @@ export default function FileUpload({
const [fileDraggedOver, setFileDraggedOver] = React.useState(false);
const inputRef = React.useRef<HTMLInputElement>(null);
const tempFileURLRef = React.useRef<string>(null);
React.useEffect(() => {
if (existingFileUrl) {
@@ -244,26 +248,37 @@ export default function FileUpload({
className="w-full relative h-full items-center justify-center overflow-hidden"
{...previewImageWrapperProps}
>
{disablePreview ? (
<Span className="opacity-50" size="small">
Image Uploaded!
</Span>
) : fileUrl.match(/\.pdf$|\.txt$/) ? (
<Row>
<FileArchive size={36} strokeWidth={1} />
<Stack className="gap-0">
<Span size="smaller" className="opacity-70">
{fileUrl}
</Span>
</Stack>
</Row>
) : (
<img
src={fileUrl}
className="w-full object-contain overflow-hidden"
{...previewImageProps}
/>
)}
<Stack className="w-full">
{disablePreview ? (
<Span className="opacity-50" size="small">
Image Uploaded!
</Span>
) : fileUrl.match(/\.pdf$|\.txt$/) ? (
<Row>
<FileArchive size={36} strokeWidth={1} />
<Stack className="gap-0">
<Span size="smaller" className="opacity-70">
{fileUrl}
</Span>
</Stack>
</Row>
) : (
<img
src={fileUrl}
className="w-full object-contain overflow-hidden"
{...previewImageProps}
/>
)}
<Tag
variant="outlined"
color="gray"
className="w-full py-2 text-sm"
>
{fileUrl}
</Tag>
</Stack>
<Button
variant="ghost"
className={twMerge(
@@ -345,6 +360,59 @@ export default function FileUpload({
>
{label || "Click to Upload File"}
</Span>
{externalSetFileURL ? (
<Row
className="flex-nowrap gap-0 items-stretch"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
}}
>
<Input
placeholder="Add Media URL"
className="text-sm"
wrapperProps={{ className: "h-full" }}
wrapperWrapperProps={{
className: "h-full",
}}
changeHandler={(value) => {
tempFileURLRef.current = value;
}}
onKeyUp={(e) => {
if (e.key == "Enter") {
if (tempFileURLRef.current) {
setFileUrl(
tempFileURLRef.current
);
externalSetFileURL(
tempFileURLRef.current
);
}
}
}}
/>
<Button
title="Add Media URL"
variant="outlined"
className="py-0 px-3"
color="gray"
onClick={(e) => {
e.preventDefault();
if (tempFileURLRef.current) {
setFileUrl(
tempFileURLRef.current
);
externalSetFileURL(
tempFileURLRef.current
);
}
}}
>
<span className="text-2xl">+</span>
</Button>
</Row>
) : null}
</Stack>
</Center>
</Card>
+4 -2
View File
@@ -207,14 +207,16 @@ export default function Input<KeyType extends string>(
window.clearTimeout(timeout);
if (validationRegex && !validationFunction) {
if (validationRegex) {
timeout = setTimeout(() => {
setValidity({
isValid: validationRegex.test(val),
msg: "Value mismatch",
});
}, finalDebounce);
} else if (validationFunction) {
}
if (validationFunction) {
window.clearTimeout(validationFnTimeout);
validationFnTimeout = setTimeout(() => {
+2 -2
View File
@@ -232,9 +232,9 @@ export default function Select<
}
hoverOpen
>
<Card className="min-w-[250px] text-sm p-6">
<Card className="min-w-[250px] p-6">
{typeof info == "string" ? (
<Span className="text-sm">{info}</Span>
<Span>{info}</Span>
) : (
info
)}