Skip to content

Commit

Permalink
add loader #28
Browse files Browse the repository at this point in the history
  • Loading branch information
ukorvl authored Aug 15, 2023
1 parent 069c235 commit edb7401
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 38 deletions.
9 changes: 8 additions & 1 deletion app/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
import clsx from 'clsx';
import Loader from '@/components/Loader/Loader';

const containerCn = clsx('grow', 'flex', 'justify-center', 'items-center', 'h-full', 'w-full');

/**
* @returns React component.
*/
export default function Loading() {
return <Loader />;
return (
<div className={containerCn}>
<Loader />
</div>
);
}
80 changes: 43 additions & 37 deletions components/Loader/Loader.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/**
* @file In order to render loader on the server we don't use framer motion here.
*/
'use client';

import {OnScreen} from '@ukorvl/react-on-screen';
import clsx from 'clsx';
import {ComponentProps} from 'react';
import PuffLoader from 'react-spinners/PuffLoader';

/**
* Loader size.
Expand All @@ -15,48 +16,53 @@ type LoaderSize = 'sm' | 'lg' | 'md';
type LoaderProps = {
/** @default md */
size?: LoaderSize;
/** @default false */
grow?: boolean;
/** @default white */
color?: ComponentProps<typeof PuffLoader>['color'];
};

const containerBaseCn = clsx(
'flex justify-content-center align-items-center p-4',
'transition-opacity',
'duration-300',
);
// eslint-disable-next-line jsdoc/require-jsdoc
const containerCn = (isOnScreen: boolean) =>
clsx(containerBaseCn, isOnScreen ? 'opacity-100' : 'opacity-0');

/**
* @param {LoaderProps} props Props.
* @returns React component.
*/
export default function Loader({size = 'md', grow = false}: LoaderProps) {
const containerClassName = clsx(
'absolute flex justify-content-center align-items-center p-4',
grow && 'min-h-screen w-full',
);

const bouncingElementClassName = clsx('motion-safe:animate-bounce h-5 w-5 m-2 bg-white', size);

//const bouncingElementViewBox = '0 0 24 24';

export default function Loader({size = 'md', color = 'white'}: LoaderProps) {
return (
<div
className={containerClassName}
role="status"
>
{[...new Array(3).keys()].map(x => (
<OnScreen<HTMLDivElement>>
{({ref, isOnScreen}) => (
<div
key={x}
className={bouncingElementClassName}
/>
))}
</div>
className={containerCn(isOnScreen)}
ref={ref}
>
<PuffLoader
size={mapSizeToValue(size)}
color={color}
aria-label="Loading"
role="status"
/>
</div>
)}
</OnScreen>
);
}

// function mapSizeToRem(s: LoaderSize) {
// switch (s) {
// case 'md':
// return 1;
// case 'lg':
// return 2;
// case 'sm':
// return 0.75;
// default:
// return 1;
// }
// }
// eslint-disable-next-line jsdoc/require-jsdoc
function mapSizeToValue(s: LoaderSize) {
switch (s) {
case 'md':
return 150;
case 'lg':
return 200;
case 'sm':
return 100;
default:
return 150;
}
}
16 changes: 16 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"react-hotkeys-hook": "^4.4.0",
"react-page-visibility": "^7.0.0",
"react-photoswipe-gallery": "^2.2.7",
"react-spinners": "^0.13.8",
"tailwind-merge": "^1.13.1",
"tailwindcss": "3.3.2",
"typescript": "5.0.4"
Expand Down

0 comments on commit edb7401

Please sign in to comment.