From c0c281e305784962616d8dec1306896273d3f9fa Mon Sep 17 00:00:00 2001 From: Ohans Emmanuel Date: Mon, 28 Oct 2019 05:16:57 +0100 Subject: [PATCH 1/2] handle reusable styles --- showcase/src/patterns/index.js | 53 +++++++++++++++++++++++++-------- showcase/src/patterns/usage.css | 18 +++++++++++ 2 files changed, 58 insertions(+), 13 deletions(-) create mode 100644 showcase/src/patterns/usage.css diff --git a/showcase/src/patterns/index.js b/showcase/src/patterns/index.js index 504c2b8..bf60458 100644 --- a/showcase/src/patterns/index.js +++ b/showcase/src/patterns/index.js @@ -13,6 +13,7 @@ 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 @@ -134,13 +135,17 @@ 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 [{ clapRef, clapCountRef, clapTotalRef }, setRefState] = useState({}) - const setRef = useCallback(node => { if (node !== null) { setRefState(prevRefState => ({ @@ -158,7 +163,6 @@ const MediumClap = ({ children, onClap }) => { }) const handleClapClick = () => { - // 👉 prop from HOC animationTimeline.replay() setClapState({ @@ -190,6 +194,8 @@ const MediumClap = ({ children, onClap }) => { [count, countTotal, isClicked, setRef] ) + const classNames = [styles.clap, className].join(' ').trim() + return ( @@ -209,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 ( @@ -225,18 +238,32 @@ const ClapIcon = () => { ) } -const ClapCount = () => { +const ClapCount = ({ className = '', style: userStyles = {} }) => { const { count, setRef } = useContext(MediumClapContext) + const classNames = [styles.count, className].join(' ').trim() + return ( - + +{count} ) } -const CountTotal = () => { +const CountTotal = ({ className = '', style: userStyles = {} }) => { const { countTotal, setRef } = useContext(MediumClapContext) + const classNames = [styles.total, className].join(' ').trim() + return ( - + {countTotal} ) @@ -270,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 From 518f4750a17b5f12a833b5092d87caec2f057044 Mon Sep 17 00:00:00 2001 From: Ohans Emmanuel Date: Tue, 14 Jan 2020 08:45:53 +0100 Subject: [PATCH 2/2] update #04 --- showcase/src/patterns/index.js | 215 ++++++++++++++++----------------- 1 file changed, 102 insertions(+), 113 deletions(-) diff --git a/showcase/src/patterns/index.js b/showcase/src/patterns/index.js index bf60458..1eb4356 100644 --- a/showcase/src/patterns/index.js +++ b/showcase/src/patterns/index.js @@ -10,7 +10,6 @@ import React, { } from 'react' 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' @@ -30,96 +29,93 @@ const useClapAnimation = ({ new mojs.Timeline() ) - useLayoutEffect( - () => { - if (!bounceEl || !fadeEl || !burstEl) { - return - } + useLayoutEffect(() => { + if (!bounceEl || !fadeEl || !burstEl) { + return + } - const triangleBurst = new mojs.Burst({ - parent: burstEl, - radius: { 50: 95 }, - count: 5, - angle: 30, - children: { - shape: 'polygon', - radius: { 6: 0 }, - scale: 1, - stroke: 'rgba(211,84,0 ,0.5)', - strokeWidth: 2, - angle: 210, - delay: 30, - speed: 0.2, - easing: mojs.easing.bezier(0.1, 1, 0.3, 1), - duration: tlDuration - } - }) - - const circleBurst = new mojs.Burst({ - parent: burstEl, - radius: { 50: 75 }, - angle: 25, - duration: tlDuration, - children: { - shape: 'circle', - fill: 'rgba(149,165,166 ,0.5)', - delay: 30, - speed: 0.2, - radius: { 3: 0 }, - easing: mojs.easing.bezier(0.1, 1, 0.3, 1) - } - }) - - const countAnimation = new mojs.Html({ - el: bounceEl, - isShowStart: false, - isShowEnd: true, - y: { 0: -30 }, - opacity: { 0: 1 }, + const triangleBurst = new mojs.Burst({ + parent: burstEl, + radius: { 50: 95 }, + count: 5, + angle: 30, + children: { + shape: 'polygon', + radius: { 6: 0 }, + scale: 1, + stroke: 'rgba(211,84,0 ,0.5)', + strokeWidth: 2, + angle: 210, + delay: 30, + speed: 0.2, + easing: mojs.easing.bezier(0.1, 1, 0.3, 1), duration: tlDuration - }).then({ - opacity: { 1: 0 }, - y: -80, - delay: tlDuration / 2 - }) - - const countTotalAnimation = new mojs.Html({ - el: fadeEl, - isShowStart: false, - isShowEnd: true, - opacity: { 0: 1 }, - delay: (3 * tlDuration) / 2, - duration: tlDuration, - y: { 0: -3 } - }) - - const scaleButton = new mojs.Html({ - el: burstEl, - duration: tlDuration, - scale: { 1.3: 1 }, - easing: mojs.easing.out - }) - - 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, - countTotalAnimation, - scaleButton, - circleBurst, - triangleBurst - ]) - - setAnimationTimeline(updatedAnimationTimeline) - }, - [tlDuration, animationTimeline, bounceEl, fadeEl, burstEl] - ) + const circleBurst = new mojs.Burst({ + parent: burstEl, + radius: { 50: 75 }, + angle: 25, + duration: tlDuration, + children: { + shape: 'circle', + fill: 'rgba(149,165,166 ,0.5)', + delay: 30, + speed: 0.2, + radius: { 3: 0 }, + easing: mojs.easing.bezier(0.1, 1, 0.3, 1) + } + }) + + const countAnimation = new mojs.Html({ + el: bounceEl, + isShowStart: false, + isShowEnd: true, + y: { 0: -30 }, + opacity: { 0: 1 }, + duration: tlDuration + }).then({ + opacity: { 1: 0 }, + y: -80, + delay: tlDuration / 2 + }) + + const countTotalAnimation = new mojs.Html({ + el: fadeEl, + isShowStart: false, + isShowEnd: true, + opacity: { 0: 1 }, + delay: (3 * tlDuration) / 2, + duration: tlDuration, + y: { 0: -3 } + }) + + const scaleButton = new mojs.Html({ + el: burstEl, + duration: tlDuration, + scale: { 1.3: 1 }, + easing: mojs.easing.out + }) + + 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, + countTotalAnimation, + scaleButton, + circleBurst, + triangleBurst + ]) + + setAnimationTimeline(updatedAnimationTimeline) + }, [tlDuration, animationTimeline, bounceEl, fadeEl, burstEl]) return animationTimeline } @@ -174,15 +170,12 @@ const MediumClap = ({ const componentJustMounted = useRef(true) - useEffect( - () => { - if (!componentJustMounted.current) { - onClap(clapState) - } - componentJustMounted.current = false - }, - [count, onClap] - ) + useEffect(() => { + if (!componentJustMounted.current) { + onClap(clapState) + } + componentJustMounted.current = false + }, [count, onClap]) const memoizedValue = useMemo( () => ({ @@ -269,26 +262,18 @@ const CountTotal = ({ className = '', style: userStyles = {} }) => { ) } -const ClapInfo = ({ info }) => { - const { countTotal } = useContext(MediumClapContext) - return ( -
- {info || wordConverter.toWords(countTotal)} claps! -
- ) -} - MediumClap.Icon = ClapIcon MediumClap.Count = ClapCount MediumClap.Total = CountTotal -MediumClap.Info = ClapInfo /** ==================================== * 🔰USAGE Below's how a potential user may consume the component API ==================================== **/ - +const Info = ({ info }) => { + return
{info}
+} const Usage = () => { const [total, setTotal] = useState(0) @@ -297,12 +282,16 @@ const Usage = () => { } return ( - - - - - - +
+ + + + + + {!!total && ( + + )} +
) }