|
import React from 'react'; |
|
import classNames from 'classnames'; |
|
import { Link } from 'gatsby'; |
|
|
|
import styles from './button.module.scss'; |
|
|
|
|
|
export const Button = ({ className, tag = 'button', size, theme, children, ...attributes }) => { |
|
const buttonRef = React.useRef(null); |
|
const borderInnerGradientRef = React.useRef(null); |
|
const blurInnerGradientRef = React.useRef(null); |
|
|
|
const handleButtonHover = () => { |
|
const button = buttonRef.current; |
|
const borderInnerGradient = borderInnerGradientRef.current; |
|
const blurInnerGradient = blurInnerGradientRef.current; |
|
|
|
if (!button || !borderInnerGradient || !blurInnerGradient) return; |
|
|
|
const buttonDataset = button.dataset; |
|
let { currentAngle, isAnimationInProgress } = buttonDataset; |
|
if (!currentAngle) currentAngle = 0; |
|
if (!isAnimationInProgress) isAnimationInProgress = 'false'; // Because values in data are strings |
|
|
|
if (isAnimationInProgress === 'false') { |
|
currentAngle = Number(currentAngle) + 360; |
|
|
|
borderInnerGradient.style.cssText = `transform: rotate(${currentAngle}deg)`; |
|
blurInnerGradient.style.cssText = `transform: rotate(${currentAngle}deg)`; |
|
|
|
buttonDataset.currentAngle = currentAngle; |
|
buttonDataset.isAnimationInProgress = 'true'; |
|
|
|
setTimeout(() => { |
|
buttonDataset.isAnimationInProgress = 'false'; |
|
}, 2000); |
|
} |
|
}; |
|
|
|
const wrapperClassName = classNames( |
|
styles.wrapper, |
|
{ [styles.wrapper_size_lg]: size === 'lg' }, |
|
{ [styles.wrapper_size_sm]: size === 'sm' }, |
|
{ [styles.wrapper_theme_additional]: theme === 'additional' }, |
|
{ [styles.wrapper_theme_transparent]: theme === 'transparent' }, |
|
{ [styles.wrapper_theme_gradientPrimary]: theme === 'gradient-primary' }, |
|
{ [styles.wrapper_theme_gradientSecondary]: theme === 'gradient-secondary' }, |
|
className, |
|
); |
|
|
|
const innerContent = ( |
|
<> |
|
{ |
|
(theme === 'gradient-primary' || theme === 'gradient-secondary') && ( |
|
<> |
|
<span className={styles.border}> |
|
<span className={styles.borderInner}> |
|
<span className={styles.borderInnerSpace}/> |
|
<span className={styles.borderInnerGradient} ref={borderInnerGradientRef}/> |
|
</span> |
|
</span> |
|
|
|
<span className={styles.blur}> |
|
<span className={styles.blurInner}> |
|
<span className={styles.blurInnerSpace}/> |
|
<span className={styles.blurInnerGradient} ref={blurInnerGradientRef}/> |
|
</span> |
|
</span> |
|
</> |
|
) |
|
} |
|
<span className={styles.text}>{children}</span> |
|
</> |
|
); |
|
|
|
switch (tag) { |
|
case 'a': |
|
return ( |
|
<a |
|
className={wrapperClassName} |
|
onMouseEnter={handleButtonHover} |
|
ref={buttonRef} |
|
{...attributes} |
|
> |
|
{innerContent} |
|
</a> |
|
); |
|
case 'link': |
|
return ( |
|
<Link |
|
className={wrapperClassName} |
|
onMouseEnter={handleButtonHover} |
|
ref={buttonRef} |
|
{...attributes} |
|
> |
|
{innerContent} |
|
</Link> |
|
); |
|
case 'button': |
|
default: |
|
return ( |
|
<button |
|
className={wrapperClassName} |
|
type={'button'} |
|
onMouseEnter={handleButtonHover} |
|
ref={buttonRef} |
|
{...attributes} |
|
> |
|
{innerContent} |
|
</button> |
|
); |
|
} |
|
}; |