UNPKG

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