Replace ErrorBoundary fallback with Fluent UI styles and dialog compliance
This commit is contained in:
@@ -315,6 +315,8 @@ Reference: `Docs/Refactoring.md` for full analysis of each issue.
|
||||
|
||||
**Docs changes needed:** None.
|
||||
|
||||
**Status:** Completed.
|
||||
|
||||
**Why this is needed:** The architecture explicitly forbids building custom modal overlays ("Use Fluent UI `<Dialog>` for modals and confirmations — never build custom modal overlays"). Hand-built modals bypass Fluent UI's accessibility tree (focus trap, ARIA roles, portal rendering) and duplicate boilerplate that the library provides. A Fluent `<Dialog>` is keyboard-accessible, screen-reader-compatible, and inherits the theme automatically.
|
||||
|
||||
---
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
* Catches render-time exceptions in child components and shows a fallback UI.
|
||||
*/
|
||||
import React from "react";
|
||||
import { Button, makeStyles, Text, tokens } from "@fluentui/react-components";
|
||||
|
||||
interface ErrorBoundaryState {
|
||||
hasError: boolean;
|
||||
@@ -14,11 +15,49 @@ interface ErrorBoundaryProps {
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
interface ErrorBoundaryFallbackProps {
|
||||
message: string;
|
||||
onReload: () => void;
|
||||
}
|
||||
|
||||
const useFallbackStyles = makeStyles({
|
||||
root: {
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
minHeight: "100vh",
|
||||
padding: tokens.spacingVerticalL,
|
||||
textAlign: "center",
|
||||
gap: tokens.spacingVerticalM,
|
||||
},
|
||||
message: {
|
||||
maxWidth: "40rem",
|
||||
},
|
||||
});
|
||||
|
||||
function ErrorBoundaryFallback({ message, onReload }: ErrorBoundaryFallbackProps): React.ReactElement {
|
||||
const styles = useFallbackStyles();
|
||||
|
||||
return (
|
||||
<div className={styles.root} role="alert">
|
||||
<Text as="h1" size={700} weight="semibold">
|
||||
Something went wrong
|
||||
</Text>
|
||||
<Text size={300} className={styles.message}>
|
||||
{message}
|
||||
</Text>
|
||||
<Button appearance="primary" onClick={onReload}>
|
||||
Reload
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
||||
constructor(props: ErrorBoundaryProps) {
|
||||
super(props);
|
||||
this.state = { hasError: false, errorMessage: null };
|
||||
this.handleReload = this.handleReload.bind(this);
|
||||
}
|
||||
|
||||
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
||||
@@ -29,31 +68,17 @@ export class ErrorBoundary extends React.Component<ErrorBoundaryProps, ErrorBoun
|
||||
console.error("ErrorBoundary caught an error", { error, errorInfo });
|
||||
}
|
||||
|
||||
handleReload(): void {
|
||||
handleReload = (): void => {
|
||||
window.location.reload();
|
||||
}
|
||||
};
|
||||
|
||||
render(): React.ReactNode {
|
||||
if (this.state.hasError) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
minHeight: "100vh",
|
||||
padding: "24px",
|
||||
textAlign: "center",
|
||||
}}
|
||||
role="alert"
|
||||
>
|
||||
<h1>Something went wrong</h1>
|
||||
<p>{this.state.errorMessage ?? "Please try reloading the page."}</p>
|
||||
<button type="button" onClick={this.handleReload} style={{ marginTop: "16px" }}>
|
||||
Reload
|
||||
</button>
|
||||
</div>
|
||||
<ErrorBoundaryFallback
|
||||
message={this.state.errorMessage ?? "Please try reloading the page."}
|
||||
onReload={this.handleReload}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user