@cerberus-design/react
Version:
The Cerberus Design React component library.
208 lines (205 loc) • 6.31 kB
JavaScript
'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 };