diff --git a/site/src/components/Loader/Loader.tsx b/site/src/components/Loader/Loader.tsx index e62156955cd9f..589cbd72b2331 100644 --- a/site/src/components/Loader/Loader.tsx +++ b/site/src/components/Loader/Loader.tsx @@ -1,15 +1,20 @@ import type { Interpolation, Theme } from "@emotion/react"; -import CircularProgress from "@mui/material/CircularProgress"; +import { Spinner } from "components/Spinner/Spinner"; import type { FC, HTMLAttributes } from "react"; interface LoaderProps extends HTMLAttributes { fullscreen?: boolean; size?: number; + /** + * A label for the loader. This is used for accessibility purposes. + */ + label?: string; } export const Loader: FC = ({ fullscreen, size = 26, + label = "Loading...", ...attrs }) => { return ( @@ -18,7 +23,7 @@ export const Loader: FC = ({ data-testid="loader" {...attrs} > - + ); }; diff --git a/site/src/components/Spinner/Spinner.tsx b/site/src/components/Spinner/Spinner.tsx new file mode 100644 index 0000000000000..5b20e2e54c5ef --- /dev/null +++ b/site/src/components/Spinner/Spinner.tsx @@ -0,0 +1,22 @@ +import CircularProgress, { + type CircularProgressProps, +} from "@mui/material/CircularProgress"; +import isChromatic from "chromatic/isChromatic"; +import type { FC } from "react"; + +/** + * Spinner component used to indicate loading states. This component abstracts + * the MUI CircularProgress to provide better control over its rendering, + * especially in snapshot tests with Chromatic. + */ +export const Spinner: FC = (props) => { + /** + * During Chromatic snapshots, we render the spinner as determinate to make it + * static without animations, using a deterministic value (75%). + */ + if (isChromatic()) { + props.variant = "determinate"; + props.value = 75; + } + return ; +};