Skip to content

Instantly share code, notes, and snippets.

@SilencerWeb
Created October 8, 2019 10:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SilencerWeb/5ca3e0402f211b7ec3d417038ea417ed to your computer and use it in GitHub Desktop.
Save SilencerWeb/5ca3e0402f211b7ec3d417038ea417ed to your computer and use it in GitHub Desktop.
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>
);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment