UNPKG

@cerberus-design/react

Version:

The Cerberus Design React component library.

208 lines (205 loc) 6.31 kB
'use client'; import { jsxs, jsx } from 'react/jsx-runtime'; import { useMemo, useCallback } from 'react'; import { fileStatus } from 'styled-system/recipes'; import { cx, css } from 'styled-system/css'; import { vstack, hstack } from 'styled-system/patterns'; import { useCerberusContext } from '../../context/cerberus.js'; import { ProgressBar } from '../progress/progress-bar.js'; import { Avatar } from '../avatar/avatar.js'; import { Field } from '../field/field.js'; import { FieldHelperText } from '../field/primitives.js'; import { IconButton } from '../icon-button/button.js'; var processStatus = /* @__PURE__ */ ((processStatus2) => { processStatus2["TODO"] = "todo"; processStatus2["PROCESSING"] = "processing"; processStatus2["DONE"] = "done"; processStatus2["ERROR"] = "error"; return processStatus2; })(processStatus || {}); function FileStatus(props) { const { file, now, status, onClick, ...nativeProps } = props; const actionLabel = useMemo(() => getStatusActionLabel(status), [status]); const palette = useMemo(() => getPalette(status), [status]); const modalIconPalette = useMemo(() => getModalIconPalette(status), [status]); const styles = useMemo(() => { switch (status) { case "todo" /* TODO */: return fileStatus({ status: "todo" }); case "processing" /* PROCESSING */: return fileStatus({ status: "processing" }); case "done" /* DONE */: return fileStatus({ status: "done" }); case "error" /* ERROR */: return fileStatus({ status: "error" }); default: return fileStatus(); } }, [status]); const handleClick = useCallback( (e) => { const actionStatus = getStatusActionLabel( status ).toLocaleLowerCase(); onClick(actionStatus, e); }, [onClick, status] ); return /* @__PURE__ */ jsxs( "div", { ...nativeProps, className: cx(nativeProps.className, styles.root, hstack()), children: [ /* @__PURE__ */ jsx( Avatar, { gradient: modalIconPalette, fallback: /* @__PURE__ */ jsx(MatchFileStatusIcon, { size: 24, status }) } ), /* @__PURE__ */ jsxs( "div", { className: vstack({ alignItems: "flex-start", gap: "0.12rem", w: "full" }), children: [ /* @__PURE__ */ jsx( "small", { className: css({ color: "page.text.initial", textStyle: "label-sm" }), children: file } ), /* @__PURE__ */ jsx( ProgressBar, { id: props.id, label: "File upload status", now, size: "sm" } ), /* @__PURE__ */ jsx(Field, { label: "", invalid: modalIconPalette === "hades-dark", children: /* @__PURE__ */ jsx( FieldHelperText, { className: css({ color: "page.text.100" }), id: `help:${file}`, children: /* @__PURE__ */ jsx(MatchFileStatusText, { status, now }) } ) }) ] } ), /* @__PURE__ */ jsx( IconButton, { ariaLabel: actionLabel, onClick: handleClick, palette, size: "sm", children: /* @__PURE__ */ jsx(MatchStatusAction, { status }) } ) ] } ); } function MatchFileStatusIcon(props) { const { icons } = useCerberusContext(); const { waitingFileUploader: TodoIcon, fileUploader: FileUploaderIcon, invalidAlt: InvalidIcon, successNotification: DoneIcon } = icons; switch (props.status) { case "todo" /* TODO */: return /* @__PURE__ */ jsx(TodoIcon, { size: props.size }); case "processing" /* PROCESSING */: return /* @__PURE__ */ jsx(FileUploaderIcon, { size: props.size }); case "done" /* DONE */: return /* @__PURE__ */ jsx(DoneIcon, { size: props.size }); case "error" /* ERROR */: return /* @__PURE__ */ jsx(InvalidIcon, { size: props.size }); default: throw new Error("Unknown status"); } } function MatchFileStatusText(props) { switch (props.status) { case "todo" /* TODO */: return "Waiting to upload"; case "processing" /* PROCESSING */: return `${props.now}% Complete`; case "done" /* DONE */: return "File uploaded successfully"; case "error" /* ERROR */: return "There was an error uploading the file"; default: throw new Error("Invalid status"); } } function MatchStatusAction(props) { const { icons } = useCerberusContext(); const { close: CloseIcon, redo: RedoIcon, delete: TrashIcon } = icons; switch (props.status) { case "todo" /* TODO */: case "processing" /* PROCESSING */: return /* @__PURE__ */ jsx(CloseIcon, {}); case "error" /* ERROR */: return /* @__PURE__ */ jsx(RedoIcon, {}); case "done" /* DONE */: return /* @__PURE__ */ jsx(TrashIcon, {}); default: throw new Error("Invalid status"); } } function getStatusActionLabel(status) { switch (status) { case "todo" /* TODO */: case "processing" /* PROCESSING */: return "Cancel"; case "error" /* ERROR */: return "Retry"; case "done" /* DONE */: return "Delete"; default: return ""; } } function getPalette(status) { switch (status) { case "todo" /* TODO */: case "processing" /* PROCESSING */: return "danger"; case "error" /* ERROR */: return "action"; case "done" /* DONE */: return "danger"; default: return "action"; } } function getModalIconPalette(status) { switch (status) { case "todo" /* TODO */: case "processing" /* PROCESSING */: return "charon-light"; case "error" /* ERROR */: return "hades-dark"; case "done" /* DONE */: return "thanatos-dark"; default: return "charon-light"; } } export { FileStatus, processStatus };