Skip to content

Instantly share code, notes, and snippets.

@arleighdickerson
Last active July 9, 2023 17:13
Show Gist options
  • Save arleighdickerson/4554f5b7ca8e6ad891a3a1e51423d1cf to your computer and use it in GitHub Desktop.
Save arleighdickerson/4554f5b7ca8e6ad891a3a1e51423d1cf to your computer and use it in GitHub Desktop.
LoadScreen
import { CSSProperties, PropsWithChildren } from 'react';
import * as colors from 'tailwindcss/colors';
export interface ContentProps {
header?: string;
message?: string;
}
export enum Variant {
SPINNING,
STATIC,
}
export interface StyleProps {
color: string;
variant: Variant;
visible: boolean;
opacity: 75 | 100;
}
export type Props = ContentProps & Partial<StyleProps>;
function classNames(...classes: (string | null | boolean)[]) {
return classes.filter(Boolean).join(' ');
}
function Content(props: ContentProps) {
const { header = '\u00A0', message = '\u00A0' } = props;
return (
<>
<h2 className="static text-center text-xl font-semibold">{header}</h2>
<p className="w-1/3 text-center">{message}</p>
</>
);
}
function getStylesForVariant(props: StyleProps): CSSProperties {
const { variant, color } = props;
const styles: CSSProperties = {};
switch (variant) {
case Variant.SPINNING:
styles.borderBottomColor = color;
styles.borderLeftColor = color;
styles.borderRightColor = color;
break;
case Variant.STATIC:
styles.borderColor = color;
break;
default:
}
return styles;
}
function getClassNameForVariant(props: StyleProps, visible: boolean) {
const classes: string[] = [
'ease-linear',
'rounded-full',
'border-8',
'border-t-8',
'border-gray-200',
'h-32',
'w-32',
'mb-4',
];
switch (props.variant) {
case Variant.SPINNING:
if (visible) {
classes.unshift('animate-spin');
}
break;
default:
}
return classNames(...classes);
}
const defaultStyleProps: StyleProps = {
variant: Variant.SPINNING,
color: colors.cyan['800'],
visible: true,
opacity: 100,
};
export default function LoadScreen(props: PropsWithChildren<Props>) {
const { header, message }: ContentProps = props;
const styleProps: StyleProps = { ...defaultStyleProps, ...props };
const className = classNames(
'fixed',
'top-0',
'left-0',
'right-0',
'bottom-0',
'w-full',
'h-screen',
'overflow-hidden',
'bg-gray-50',
`opacity-${props.opacity}`,
'flex',
'flex-col',
'items-center',
'justify-center',
styleProps.visible ? 'visible' : 'invisible',
);
return (
<div className={className}>
<div style={getStylesForVariant(styleProps)} className={getClassNameForVariant(styleProps, styleProps.visible)} />
<Content header={header} message={message} />
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment