zentrixui
Version:
ZentrixUI - A modern, highly customizable and accessible React file upload component library with multiple variants, JSON-based configuration, and excellent developer experience.
173 lines (172 loc) • 6.95 kB
JavaScript
import { jsxs, jsx } from "react/jsx-runtime";
import { Component } from "react";
import { cn } from "../../utils/theme.js";
import TriangleAlert from "../../node_modules/lucide-react/dist/esm/icons/triangle-alert.js";
import X from "../../node_modules/lucide-react/dist/esm/icons/x.js";
import RefreshCw from "../../node_modules/lucide-react/dist/esm/icons/refresh-cw.js";
class FileUploadErrorBoundary extends Component {
constructor(props) {
super(props);
this.state = {
hasError: false,
error: null,
errorInfo: null,
errorId: ""
};
}
static getDerivedStateFromError(error) {
const errorId = `error_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
return {
hasError: true,
error,
errorId
};
}
componentDidCatch(error, errorInfo) {
this.setState({
error,
errorInfo
});
this.props.onError?.(error, errorInfo);
console.error("FileUpload Error Boundary caught an error:", error, errorInfo);
}
handleRetry = () => {
this.setState({
hasError: false,
error: null,
errorInfo: null,
errorId: ""
});
};
handleDismiss = () => {
this.setState({
hasError: false,
error: null,
errorInfo: null,
errorId: ""
});
};
render() {
if (this.state.hasError) {
if (this.props.fallback) {
return this.props.fallback;
}
return /* @__PURE__ */ jsxs(
"div",
{
className: cn(
"file-upload-error-boundary",
"border border-red-200 rounded-lg p-6 bg-red-50",
"text-red-900 space-y-4",
this.props.className
),
role: "alert",
"aria-live": "assertive",
"aria-labelledby": `error-title-${this.state.errorId}`,
"aria-describedby": `error-description-${this.state.errorId}`,
children: [
/* @__PURE__ */ jsxs("div", { className: "flex items-start gap-3", children: [
/* @__PURE__ */ jsx(
TriangleAlert,
{
className: "w-5 h-5 text-red-500 flex-shrink-0 mt-0.5",
"aria-hidden": "true"
}
),
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
/* @__PURE__ */ jsx(
"h3",
{
id: `error-title-${this.state.errorId}`,
className: "text-sm font-medium text-red-800",
children: "Something went wrong with the file upload component"
}
),
/* @__PURE__ */ jsx(
"p",
{
id: `error-description-${this.state.errorId}`,
className: "mt-1 text-sm text-red-700",
children: "An unexpected error occurred. You can try refreshing the component or contact support if the problem persists."
}
),
this.props.showErrorDetails && this.state.error && /* @__PURE__ */ jsxs("details", { className: "mt-3", children: [
/* @__PURE__ */ jsx("summary", { className: "text-sm font-medium text-red-800 cursor-pointer hover:text-red-900", children: "Technical Details" }),
/* @__PURE__ */ jsxs("div", { className: "mt-2 p-3 bg-red-100 rounded border text-xs font-mono text-red-800 overflow-auto", children: [
/* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
/* @__PURE__ */ jsx("strong", { children: "Error:" }),
" ",
this.state.error.message
] }),
/* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
/* @__PURE__ */ jsx("strong", { children: "Stack:" }),
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap mt-1", children: this.state.error.stack })
] }),
this.state.errorInfo && /* @__PURE__ */ jsxs("div", { children: [
/* @__PURE__ */ jsx("strong", { children: "Component Stack:" }),
/* @__PURE__ */ jsx("pre", { className: "whitespace-pre-wrap mt-1", children: this.state.errorInfo.componentStack })
] })
] })
] })
] }),
/* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick: this.handleDismiss,
className: "text-red-400 hover:text-red-500 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 rounded",
"aria-label": "Dismiss error",
children: /* @__PURE__ */ jsx(X, { className: "w-4 h-4" })
}
)
] }),
/* @__PURE__ */ jsxs("div", { className: "flex gap-3 pt-2", children: [
/* @__PURE__ */ jsxs(
"button",
{
type: "button",
onClick: this.handleRetry,
className: cn(
"inline-flex items-center gap-2 px-3 py-2 text-sm font-medium",
"text-red-700 bg-red-100 border border-red-300 rounded-md",
"hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2",
"transition-colors duration-200"
),
children: [
/* @__PURE__ */ jsx(RefreshCw, { className: "w-4 h-4" }),
"Try Again"
]
}
),
/* @__PURE__ */ jsx(
"button",
{
type: "button",
onClick: () => window.location.reload(),
className: cn(
"inline-flex items-center px-3 py-2 text-sm font-medium",
"text-red-700 bg-transparent border border-red-300 rounded-md",
"hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2",
"transition-colors duration-200"
),
children: "Refresh Page"
}
)
] })
]
}
);
}
return this.props.children;
}
}
const withErrorBoundary = (Component2, errorBoundaryProps) => {
const WrappedComponent = (props) => /* @__PURE__ */ jsx(FileUploadErrorBoundary, { ...errorBoundaryProps, children: /* @__PURE__ */ jsx(Component2, { ...props }) });
WrappedComponent.displayName = `withErrorBoundary(${Component2.displayName || Component2.name})`;
return WrappedComponent;
};
export {
FileUploadErrorBoundary,
withErrorBoundary
};
//# sourceMappingURL=error-boundary.js.map