diff --git a/showcase/src/patterns/index.js b/showcase/src/patterns/index.js
index 2809f8f..4dabdcc 100644
--- a/showcase/src/patterns/index.js
+++ b/showcase/src/patterns/index.js
@@ -1,6 +1,8 @@
import React, {
useState,
useEffect,
+ useCallback,
+ useLayoutEffect,
useContext,
useMemo,
useRef,
@@ -11,21 +13,31 @@ import mojs from 'mo-js'
import wordConverter from 'number-to-words'
import { generateRandomNumber } from '../utils/generateRandomNumber'
import styles from './index.css'
+import userStyles from './usage.css'
/** ====================================
* 🔰Hook
Hook for Animation
==================================== **/
-const useClapAnimation = ({ duration: tlDuration }) => {
+const useClapAnimation = ({
+ duration: tlDuration,
+ bounceEl,
+ fadeEl,
+ burstEl
+}) => {
const [animationTimeline, setAnimationTimeline] = useState(
new mojs.Timeline()
)
- useEffect(
+ useLayoutEffect(
() => {
+ if (!bounceEl || !fadeEl || !burstEl) {
+ return
+ }
+
const triangleBurst = new mojs.Burst({
- parent: '#clap',
+ parent: burstEl,
radius: { 50: 95 },
count: 5,
angle: 30,
@@ -44,7 +56,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {
})
const circleBurst = new mojs.Burst({
- parent: '#clap',
+ parent: burstEl,
radius: { 50: 75 },
angle: 25,
duration: tlDuration,
@@ -59,7 +71,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {
})
const countAnimation = new mojs.Html({
- el: '#clapCount',
+ el: bounceEl,
isShowStart: false,
isShowEnd: true,
y: { 0: -30 },
@@ -72,7 +84,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {
})
const countTotalAnimation = new mojs.Html({
- el: '#clapCountTotal',
+ el: fadeEl,
isShowStart: false,
isShowEnd: true,
opacity: { 0: 1 },
@@ -82,14 +94,19 @@ const useClapAnimation = ({ duration: tlDuration }) => {
})
const scaleButton = new mojs.Html({
- el: '#clap',
+ el: burstEl,
duration: tlDuration,
scale: { 1.3: 1 },
easing: mojs.easing.out
})
- const clap = document.getElementById('clap')
- clap.style.transform = 'scale(1, 1)'
+ if (typeof burstEl === 'string') {
+ clap.style.transform = 'scale(1, 1)'
+ const el = document.getElementById(id)
+ el.style.transform = 'scale(1, 1)'
+ } else {
+ burstEl.style.transform = 'scale(1, 1)'
+ }
const updatedAnimationTimeline = animationTimeline.add([
countAnimation,
@@ -101,7 +118,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {
setAnimationTimeline(updatedAnimationTimeline)
},
- [tlDuration, animationTimeline]
+ [tlDuration, animationTimeline, bounceEl, fadeEl, burstEl]
)
return animationTimeline
@@ -118,14 +135,34 @@ const initialState = {
const MediumClapContext = createContext()
const { Provider } = MediumClapContext
-const MediumClap = ({ children, onClap }) => {
+const MediumClap = ({
+ children,
+ onClap,
+ className = '',
+ style: userStyles = {}
+}) => {
const MAXIMUM_USER_CLAP = 50
const [clapState, setClapState] = useState(initialState)
const { count, countTotal, isClicked } = clapState
- const animationTimeline = useClapAnimation({ duration: 300 })
+ const [{ clapRef, clapCountRef, clapTotalRef }, setRefState] = useState({})
+ const setRef = useCallback(node => {
+ if (node !== null) {
+ setRefState(prevRefState => ({
+ ...prevRefState,
+ [node.dataset.refkey]: node
+ }))
+ }
+ }, [])
+
+ const animationTimeline = useClapAnimation({
+ duration: 300,
+ bounceEl: clapCountRef,
+ fadeEl: clapTotalRef,
+ burstEl: clapRef
+ })
+
const handleClapClick = () => {
- // 👉 prop from HOC
animationTimeline.replay()
setClapState({
@@ -151,14 +188,24 @@ const MediumClap = ({ children, onClap }) => {
() => ({
count,
countTotal,
- isClicked
+ isClicked,
+ setRef
}),
- [count, countTotal, isClicked]
+ [count, countTotal, isClicked, setRef]
)
+ const classNames = [styles.clap, className].join(' ').trim()
+
return (
-
@@ -170,15 +217,20 @@ const MediumClap = ({ children, onClap }) => {
Smaller Component used by
==================================== **/
-const ClapIcon = () => {
+const ClapIcon = ({ className = '', style: userStyles = {} }) => {
const { isClicked } = useContext(MediumClapContext)
+ const classNames = [styles.icon, isClicked ? styles.checked : '', className]
+ .join(' ')
+ .trim()
+
return (
)
}
-const ClapCount = () => {
- const { count } = useContext(MediumClapContext)
+const ClapCount = ({ className = '', style: userStyles = {} }) => {
+ const { count, setRef } = useContext(MediumClapContext)
+ const classNames = [styles.count, className].join(' ').trim()
+
return (
-
+
+{count}
)
}
-const CountTotal = () => {
- const { countTotal } = useContext(MediumClapContext)
+const CountTotal = ({ className = '', style: userStyles = {} }) => {
+ const { countTotal, setRef } = useContext(MediumClapContext)
+ const classNames = [styles.total, className].join(' ').trim()
+
return (
-
+
{countTotal}
)
@@ -231,10 +297,10 @@ const Usage = () => {
}
return (
-
-
-
-
+
+
+
+
)
diff --git a/showcase/src/patterns/usage.css b/showcase/src/patterns/usage.css
new file mode 100644
index 0000000..bafb86d
--- /dev/null
+++ b/showcase/src/patterns/usage.css
@@ -0,0 +1,18 @@
+/** total **/
+
+.total {
+ color: #896EAF;
+}
+
+ /* count */
+.count {
+ background: #896EAF;
+}
+
+ /* clap */
+.clap {
+ border: 1px solid #896EAF;
+}
+.clap:hover {
+ border: 1px solid #896EAF;
+}
\ No newline at end of file