diff --git a/src/components/Spinner.tsx b/src/components/Spinner.tsx new file mode 100644 index 0000000..f319112 --- /dev/null +++ b/src/components/Spinner.tsx @@ -0,0 +1,86 @@ +import React, { HTMLAttributes, useMemo } from 'react'; + +export interface Props extends HTMLAttributes { + /** Variant of colors */ + color?: 'primary' | 'secondary' | 'black' | 'white'; + /** variant of background colors */ + bgColor?: 'primary' | 'secondary' | 'black' | 'white'; + /** variant of size */ + size?: 'small' | 'medium' | 'large'; +} + +const BASE_SPINNER_CLASSES = + 'mr-2 animate-spin'; + +const getColorClasses = (color: string) => { + switch (color) { + default: + case 'primary': + return 'fill-primary'; + case 'secondary': + return 'fill-secondary'; + case 'black': + return 'fill-black'; + case 'white': + return 'fill-white'; + } +}; + +const getBgColorClasses = (bgColor: string) => { + switch (bgColor) { + default: + case 'primary': + return 'text-primary'; + case 'secondary': + return 'text-secondary'; + case 'black': + return 'text-black'; + case 'white': + return 'text-white'; + } + }; + + const getSizeClasses = (size: string) => { + switch (size) { + default: + case 'small': + return 'w-4 h-4'; + case 'medium': + return 'w-8 h-8'; + case 'large': + return 'w-12 h-12'; + } + }; + +/** Spinner component */ +export const Spinner = ({ color = 'primary', bgColor = 'black', size = 'small' }: Props) => { + const computedClasses = useMemo(() => { + const colorClasses = getColorClasses(color); + const bgColorClasses = getBgColorClasses(bgColor); + const sizeClasses = getSizeClasses(size); + + return [colorClasses, bgColorClasses, sizeClasses].join(' '); + }, [color, bgColor, size]); + + return ( +
+ + Loading... +
+ ); +}; diff --git a/stories/Spinner.stories.tsx b/stories/Spinner.stories.tsx new file mode 100644 index 0000000..efc4103 --- /dev/null +++ b/stories/Spinner.stories.tsx @@ -0,0 +1,53 @@ +import React from 'react'; +import { Meta, Story } from '@storybook/react'; +import { Spinner, Props } from '../src/components/Spinner'; + +const meta: Meta = { + title: 'Components/Atoms/Spinner', + component: Spinner, +}; + +export default meta; + +const Template: Story = args => ; + +export const SpinnerPrimary = Template.bind({}); +SpinnerPrimary.args = { + color: 'primary', + bgColor: 'secondary', +}; + +export const SpinnerSecondary = Template.bind({}); +SpinnerSecondary.args = { + color: 'secondary', + bgColor: 'primary', +}; + +export const SpinnerBlack = Template.bind({}); +SpinnerBlack.args = { + color: 'black', + bgColor: 'white' +}; + +export const SpinnerWhite = Template.bind({}); +SpinnerWhite.args = { + color: 'white', + bgColor: 'black', +}; + +export const SpinnerSmall = Template.bind({}); +SpinnerSmall.args = { + size: 'small', +}; + +export const SpinnerMedium = Template.bind({}); +SpinnerMedium.args = { + size: 'medium', +}; + +export const SpinnerLarge = Template.bind({}); +SpinnerLarge.args = { + size: 'large', +}; + +