Skip to content

Instantly share code, notes, and snippets.

@DmitryOlkhovoi
Created January 21, 2020 10:53
Show Gist options
  • Save DmitryOlkhovoi/1d02c94612d453782b0f2c172a7a1c65 to your computer and use it in GitHub Desktop.
Save DmitryOlkhovoi/1d02c94612d453782b0f2c172a7a1c65 to your computer and use it in GitHub Desktop.
import React, { FunctionComponent, ButtonHTMLAttributes, useState } from 'react';
import uuid from 'uuid/v4';
import classnames from 'classnames';
export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
primary?: boolean,
accent?: boolean,
circle?: boolean,
ripple?: boolean,
additionalClass?: string,
}
const Button: FunctionComponent<ButtonProps> = (props) => {
const [rippleElements, setRippleElements] = useState<JSX.Element[]>([]);
const {primary, accent, circle, ripple, additionalClass, children} = props;
const classNames = classnames(
'btn',
{
primary
},
{
'with-ripple': ripple
},
{
circle
},
{
accent
},
additionalClass
);
function onAnimationEnd(key: string) {
setRippleElements(rippleElements => rippleElements.filter(element => element.key !== key));
}
function onRippleClick(event: React.MouseEvent<HTMLButtonElement, MouseEvent>) {
var rect = event.currentTarget.getBoundingClientRect();
const d = Math.max(event.currentTarget.clientWidth, event.currentTarget.clientHeight);
const left = event.clientX - rect.left - d/2 + 'px';
const top = event.clientY - rect.top - d/2 + 'px';
const rippleElement = newRippleElement(d, left, top);
setRippleElements([...rippleElements, rippleElement]);
}
function newRippleElement(d: number, left: string, top: string) {
const key = uuid();
return (
<div
key={key}
className="ripple"
style={{width: d, height: d, left, top}}
onAnimationEnd={() => onAnimationEnd(key)}
>
</div>
);
}
function renderRippleElements() {
return rippleElements;
}
return (
<button
className={classNames}
{...props}
onClick={(event) => {
if (props.onClick) {
props.onClick(event);
}
if (ripple) {
onRippleClick(event);
}
}}
>
{children}
{renderRippleElements()}
</button>
);
}
export default Button;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment