@airplane/views
Version:
A React library for building Airplane views. Views components are optimized in style and functionality to produce internal apps that are easy to build and maintain.
122 lines (121 loc) • 5.39 kB
JavaScript
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
import { createStyles, Input, Progress } from "@mantine/core";
import { Dropzone } from "@mantine/dropzone";
import { AirplaneFile } from "airplane";
import prettyBytes from "pretty-bytes";
import { forwardRef } from "react";
import { Card } from "../card/Card.js";
import { XMarkIcon, ArrowUpTrayIcon, DocumentCheckIconOutline } from "@airplane/views/icons/index.js";
import { showNotification } from "../notification/showNotification.js";
import { Stack } from "../stack/Stack.js";
import { Text } from "../text/Text.js";
import { COLORS } from "../theme/colors.js";
import { useUploadAirplaneFiles } from "./useUploadAirplaneFiles.js";
const useStyles = createStyles((theme) => ({
disabled: {
backgroundColor: theme.colorScheme === "dark" ? theme.colors.dark[6] : theme.colors.gray[0],
borderColor: theme.colorScheme === "dark" ? theme.colors.dark[5] : theme.colors.gray[2],
cursor: "not-allowed",
"& *": {
color: theme.colorScheme === "dark" ? theme.colors.dark[3] : theme.colors.gray[5]
}
},
error: {
borderColor: "red"
}
}));
const Preview = (props) => {
return /* @__PURE__ */ jsxs(Card, { p: 0, children: [
/* @__PURE__ */ jsxs(Stack, { align: "center", spacing: "sm", direction: "row", sx: {
padding: 8
}, children: [
/* @__PURE__ */ jsx(Stack, { align: "center", children: /* @__PURE__ */ jsx(DocumentCheckIconOutline, { size: "lg" }) }),
/* @__PURE__ */ jsx(Text, { lineClamp: 1, children: props.fname }),
/* @__PURE__ */ jsx(Text, { children: `(${prettyBytes(props.fsize)})` })
] }),
props.progress !== void 0 && /* @__PURE__ */ jsx(Progress, { value: props.progress, size: "xs" })
] });
};
const DropzoneFileInputComponent = /* @__PURE__ */ forwardRef(({
disableDragAndDrop,
clearable,
multiple = false,
label,
placeholder,
description,
error,
value,
id,
onChange,
required,
getUploadURL,
className,
style,
...restProps
}, ref) => {
const {
classes,
cx
} = useStyles();
const canonicalValue = value instanceof AirplaneFile ? [value] : value;
const {
onDrop,
uploads
} = useUploadAirplaneFiles({
onChange,
onLoad: (file) => showNotification({
title: "Upload successful",
message: `${file.name} uploaded successfully`,
type: "success"
}),
onError: (file, e) => showNotification({
title: "Upload failed",
message: `${file.name} upload failed: ${e.message}`,
type: "error"
}),
getUploadURL
});
const effectiveFiles = uploads.length ? uploads : canonicalValue || uploads;
const dropzoneClassName = restProps.disabled ? classes.disabled : error ? classes.error : void 0;
return /* @__PURE__ */ jsxs(Stack, { spacing: "xs", sx: {
fontSize: 14
}, children: [
/* @__PURE__ */ jsxs(Stack, { direction: "row", grow: true, children: [
/* @__PURE__ */ jsxs(Stack, { direction: "row", spacing: "xs", sx: {
fontWeight: 500,
color: COLORS.gray[7]
}, children: [
typeof label === "string" ? /* @__PURE__ */ jsx(Input.Label, { htmlFor: id, children: label }) : label,
required && /* @__PURE__ */ jsx(Text, { color: "red", disableMarkdown: true, children: "*" })
] }),
/* @__PURE__ */ jsx(Stack, { align: "end", children: clearable && effectiveFiles.length > 0 && /* @__PURE__ */ jsx(XMarkIcon, { style: {
cursor: "pointer"
}, onClick: () => {
onChange([]);
} }) })
] }),
/* @__PURE__ */ jsx(Dropzone, { className: cx(className, dropzoneClassName), style, onDrop, activateOnDrag: !disableDragAndDrop, multiple, ref, ...restProps, children: /* @__PURE__ */ jsxs(Stack, { align: "center", children: [
/* @__PURE__ */ jsxs(Dropzone.Accept, { children: [
/* @__PURE__ */ jsx(Stack, { align: "center", children: /* @__PURE__ */ jsx(ArrowUpTrayIcon, { size: "xl", color: "blue" }) }),
/* @__PURE__ */ jsx(Text, { color: "blue", children: placeholder || "Drop to upload" })
] }),
/* @__PURE__ */ jsxs(Dropzone.Reject, { children: [
/* @__PURE__ */ jsx(Stack, { align: "center", children: /* @__PURE__ */ jsx(XMarkIcon, { size: "xl", color: "red" }) }),
/* @__PURE__ */ jsx(Text, { color: "red", children: placeholder || "Drop to upload" })
] }),
/* @__PURE__ */ jsx(Dropzone.Idle, { children: effectiveFiles.length ? /* @__PURE__ */ jsx(Stack, { children: effectiveFiles.map((f, i) => f instanceof AirplaneFile ? /* @__PURE__ */ jsx(Preview, { fname: f.name, fsize: f.size }, i) : /* @__PURE__ */ jsx(Preview, { fname: f.file.name, fsize: f.file.size, progress: f.percent }, i)) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
/* @__PURE__ */ jsx(Stack, { align: "center", children: /* @__PURE__ */ jsx(ArrowUpTrayIcon, { size: "xl" }) }),
/* @__PURE__ */ jsx(Text, { children: placeholder || "Click or drag to upload" })
] }) })
] }) }),
typeof description === "string" ? /* @__PURE__ */ jsx(Text, { sx: {
color: COLORS.gray[6]
}, children: description }) : description,
typeof error === "string" ? /* @__PURE__ */ jsx(Text, { color: "red", children: error }) : error
] });
});
DropzoneFileInputComponent.displayName = "FileInputComponent";
export {
DropzoneFileInputComponent
};
//# sourceMappingURL=DropzoneFileInput.js.map