Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add ripple effect on button click
- Loading branch information
1 parent
bbe3073
commit 86d212c
Showing
6 changed files
with
115 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { useEffect, useState } from 'react' | ||
|
||
const useDebounce = <T>(value: T, delay?: number): T => { | ||
const [debouncedValue, setDebouncedValue] = useState<T>(value) | ||
|
||
useEffect(() => { | ||
const timer = setTimeout(() => setDebouncedValue(value), delay || 500) | ||
|
||
return () => { | ||
clearTimeout(timer) | ||
} | ||
}, [value, delay]) | ||
|
||
return debouncedValue | ||
} | ||
|
||
export default useDebounce |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import { useEffect, useState, RefObject, CSSProperties } from 'react' | ||
|
||
import useDebounce from './useDebounce' | ||
|
||
const useRipple = <T extends HTMLElement>(ref: RefObject<T>) => { | ||
const [ripples, setRipples] = useState<CSSProperties[]>([]) | ||
|
||
useEffect(() => { | ||
if (ref.current) { | ||
const element = ref.current | ||
|
||
const clickHandler = (e: MouseEvent) => { | ||
var rect = element.getBoundingClientRect() | ||
var left = e.clientX - rect.left | ||
var top = e.clientY - rect.top | ||
|
||
const height = element.clientHeight | ||
const width = element.clientWidth | ||
const diameter = Math.max(width, height) | ||
|
||
setRipples([ | ||
...ripples, | ||
{ | ||
top: top - diameter / 2, | ||
left: left - diameter /2, | ||
height: Math.max(width, height), | ||
width: Math.max(width, height) | ||
} | ||
]) | ||
} | ||
|
||
element.addEventListener('click', clickHandler) | ||
|
||
return () => { | ||
element.removeEventListener('click', clickHandler) | ||
} | ||
} | ||
}, [ref, ripples]) | ||
|
||
const debounced = useDebounce(ripples, 1000) | ||
useEffect(() => { | ||
if (debounced.length) { | ||
setRipples([]) | ||
} | ||
}, [debounced.length]) | ||
|
||
return ripples.map((style, i) => { | ||
return ( | ||
<span | ||
key={i} | ||
style={{ | ||
...style, | ||
position: 'absolute', | ||
backgroundColor: '#FFFFFF', | ||
opacity: "25%", | ||
transform: "scale(0)", | ||
animation: "rippleAnimation 600ms linear", | ||
borderRadius: "50%" | ||
}} | ||
/> | ||
) | ||
}) | ||
} | ||
|
||
export default useRipple |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters