Skip to content

Instantly share code, notes, and snippets.

@RickeyWard
Last active September 23, 2020 20:19
Show Gist options
  • Save RickeyWard/846f87b9ec2a484a0a9801bc3c2d9651 to your computer and use it in GitHub Desktop.
Save RickeyWard/846f87b9ec2a484a0a9801bc3c2d9651 to your computer and use it in GitHub Desktop.
React LaddaButton wrapper in Typescript with hooks
import React, { useRef, useEffect } from 'react'
import { create } from 'ladda'
import { LaddaButton as laddatype } from 'ladda/js/ladda';
export const XS = 'xs'
export const S = 's'
export const L = 'l'
export const XL = 'xl'
export const SIZES = [XS, S, L, XL] as const
export const CONTRACT = 'contract'
export const CONTRACT_OVERLAY = 'contract-overlay'
export const EXPAND_LEFT = 'expand-left'
export const EXPAND_RIGHT = 'expand-right'
export const EXPAND_UP = 'expand-up'
export const EXPAND_DOWN = 'expand-down'
export const SLIDE_LEFT = 'slide-left'
export const SLIDE_RIGHT = 'slide-right'
export const SLIDE_UP = 'slide-up'
export const SLIDE_DOWN = 'slide-down'
export const ZOOM_IN = 'zoom-in'
export const ZOOM_OUT = 'zoom-out'
export const STYLES = [
CONTRACT,
CONTRACT_OVERLAY,
EXPAND_LEFT,
EXPAND_RIGHT,
EXPAND_UP,
EXPAND_DOWN,
SLIDE_LEFT,
SLIDE_RIGHT,
SLIDE_UP,
SLIDE_DOWN,
ZOOM_IN,
ZOOM_OUT,
] as const
export interface LaddaButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
className?: string;
progress?: number;
loading?: boolean;
disabled?: boolean;
'data-color'?: string;
'data-size'?: typeof SIZES[number];
'data-style'?: typeof STYLES[number];
'data-spinner-size'?: number;
'data-spinner-color'?: string;
'data-spinner-lines'?: number;
}
const LaddaButton: React.FC<LaddaButtonProps> = ({className, children, disabled, loading, progress, ...restProps}) => {
const buttonRef = useRef<HTMLButtonElement>(null);
const laddaInstance = useRef<laddatype>();
useEffect(() => {
if(buttonRef.current)
laddaInstance.current = create(buttonRef.current);
return () => {
laddaInstance.current && laddaInstance.current.remove();
}
}, []);
useEffect(() => {
if(loading && laddaInstance.current){
laddaInstance.current.start();
} else if(laddaInstance.current){
laddaInstance.current.stop();
}
}, [loading])
useEffect(() => {
if(laddaInstance.current && typeof progress !== 'undefined')
laddaInstance.current.setProgress(progress);
}, [progress])
return (
<button
{...restProps}
className={`ladda-button ${className || ''}`}
ref={buttonRef}
disabled={disabled || loading}
>
<span className="ladda-label">{children}</span>
</button>
)
}
export default LaddaButton;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment