UNPKG

@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
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