Skip to content

#04: Reusable Styles #5

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
122 changes: 94 additions & 28 deletions showcase/src/patterns/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, {
useState,
useEffect,
useCallback,
useLayoutEffect,
useContext,
useMemo,
useRef,
Expand All @@ -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,
Expand All @@ -44,7 +56,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {
})

const circleBurst = new mojs.Burst({
parent: '#clap',
parent: burstEl,
radius: { 50: 75 },
angle: 25,
duration: tlDuration,
Expand All @@ -59,7 +71,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {
})

const countAnimation = new mojs.Html({
el: '#clapCount',
el: bounceEl,
isShowStart: false,
isShowEnd: true,
y: { 0: -30 },
Expand All @@ -72,7 +84,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {
})

const countTotalAnimation = new mojs.Html({
el: '#clapCountTotal',
el: fadeEl,
isShowStart: false,
isShowEnd: true,
opacity: { 0: 1 },
Expand All @@ -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,
Expand All @@ -101,7 +118,7 @@ const useClapAnimation = ({ duration: tlDuration }) => {

setAnimationTimeline(updatedAnimationTimeline)
},
[tlDuration, animationTimeline]
[tlDuration, animationTimeline, bounceEl, fadeEl, burstEl]
)

return animationTimeline
Expand All @@ -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({
Expand All @@ -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 (
<Provider value={memoizedValue}>
<button id='clap' className={styles.clap} onClick={handleClapClick}>
<button
ref={setRef}
data-refkey='clapRef'
className={styles.clap}
onClick={handleClapClick}
className={classNames}
style={userStyles}
>
{children}
</button>
</Provider>
Expand All @@ -170,34 +217,53 @@ const MediumClap = ({ children, onClap }) => {
Smaller Component used by <MediumClap />
==================================== **/

const ClapIcon = () => {
const ClapIcon = ({ className = '', style: userStyles = {} }) => {
const { isClicked } = useContext(MediumClapContext)
const classNames = [styles.icon, isClicked ? styles.checked : '', className]
.join(' ')
.trim()

return (
<span>
<svg
id='clapIcon'
xmlns='http://www.w3.org/2000/svg'
viewBox='-549 338 100.1 125'
className={`${styles.icon} ${isClicked && styles.checked}`}
className={classNames}
style={userStyles}
>
<path d='M-471.2 366.8c1.2 1.1 1.9 2.6 2.3 4.1.4-.3.8-.5 1.2-.7 1-1.9.7-4.3-1-5.9-2-1.9-5.2-1.9-7.2.1l-.2.2c1.8.1 3.6.9 4.9 2.2zm-28.8 14c.4.9.7 1.9.8 3.1l16.5-16.9c.6-.6 1.4-1.1 2.1-1.5 1-1.9.7-4.4-.9-6-2-1.9-5.2-1.9-7.2.1l-15.5 15.9c2.3 2.2 3.1 3 4.2 5.3zm-38.9 39.7c-.1-8.9 3.2-17.2 9.4-23.6l18.6-19c.7-2 .5-4.1-.1-5.3-.8-1.8-1.3-2.3-3.6-4.5l-20.9 21.4c-10.6 10.8-11.2 27.6-2.3 39.3-.6-2.6-1-5.4-1.1-8.3z' />
<path d='M-527.2 399.1l20.9-21.4c2.2 2.2 2.7 2.6 3.5 4.5.8 1.8 1 5.4-1.6 8l-11.8 12.2c-.5.5-.4 1.2 0 1.7.5.5 1.2.5 1.7 0l34-35c1.9-2 5.2-2.1 7.2-.1 2 1.9 2 5.2.1 7.2l-24.7 25.3c-.5.5-.4 1.2 0 1.7.5.5 1.2.5 1.7 0l28.5-29.3c2-2 5.2-2 7.1-.1 2 1.9 2 5.1.1 7.1l-28.5 29.3c-.5.5-.4 1.2 0 1.7.5.5 1.2.4 1.7 0l24.7-25.3c1.9-2 5.1-2.1 7.1-.1 2 1.9 2 5.2.1 7.2l-24.7 25.3c-.5.5-.4 1.2 0 1.7.5.5 1.2.5 1.7 0l14.6-15c2-2 5.2-2 7.2-.1 2 2 2.1 5.2.1 7.2l-27.6 28.4c-11.6 11.9-30.6 12.2-42.5.6-12-11.7-12.2-30.8-.6-42.7m18.1-48.4l-.7 4.9-2.2-4.4m7.6.9l-3.7 3.4 1.2-4.8m5.5 4.7l-4.8 1.6 3.1-3.9' />
</svg>
</span>
)
}
const ClapCount = () => {
const { count } = useContext(MediumClapContext)
const ClapCount = ({ className = '', style: userStyles = {} }) => {
const { count, setRef } = useContext(MediumClapContext)
const classNames = [styles.count, className].join(' ').trim()

return (
<span id='clapCount' className={styles.count}>
<span
ref={setRef}
data-refkey='clapCountRef'
className={classNames}
style={userStyles}
>
+{count}
</span>
)
}
const CountTotal = () => {
const { countTotal } = useContext(MediumClapContext)
const CountTotal = ({ className = '', style: userStyles = {} }) => {
const { countTotal, setRef } = useContext(MediumClapContext)
const classNames = [styles.total, className].join(' ').trim()

return (
<span id='clapCountTotal' className={styles.total}>
<span
ref={setRef}
data-refkey='clapTotalRef'
className={classNames}
style={userStyles}
>
{countTotal}
</span>
)
Expand Down Expand Up @@ -231,10 +297,10 @@ const Usage = () => {
}

return (
<MediumClap onClap={onClap}>
<MediumClap.Icon />
<MediumClap.Total />
<MediumClap.Count />
<MediumClap onClap={onClap} className={userStyles.clap}>
<MediumClap.Icon className={userStyles.icon} />
<MediumClap.Total className={userStyles.total} />
<MediumClap.Count className={userStyles.count} />
<MediumClap.Info info={`Your article has been clapped ${total} times`} />
</MediumClap>
)
Expand Down
18 changes: 18 additions & 0 deletions showcase/src/patterns/usage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/** total **/

.total {
color: #896EAF;
}

/* count */
.count {
background: #896EAF;
}

/* clap */
.clap {
border: 1px solid #896EAF;
}
.clap:hover {
border: 1px solid #896EAF;
}