From 501983f61536a809087a48081c7d4f05b2dfe3b1 Mon Sep 17 00:00:00 2001 From: srgooglo Date: Wed, 2 Mar 2022 20:34:06 +0100 Subject: [PATCH] added `LikeButton` --- .../app/src/components/LikeButton/index.jsx | 48 ++++++ .../app/src/components/LikeButton/index.less | 151 ++++++++++++++++++ packages/app/src/components/index.js | 1 + 3 files changed, 200 insertions(+) create mode 100644 packages/app/src/components/LikeButton/index.jsx create mode 100644 packages/app/src/components/LikeButton/index.less diff --git a/packages/app/src/components/LikeButton/index.jsx b/packages/app/src/components/LikeButton/index.jsx new file mode 100644 index 00000000..79a0146c --- /dev/null +++ b/packages/app/src/components/LikeButton/index.jsx @@ -0,0 +1,48 @@ +import React from "react" +import classnames from "classnames" + +import "./index.less" + +export default (props) => { + const [liked, setLiked] = React.useState(props.defaultLiked ?? false) + const [clicked, setCliked] = React.useState(false) + + const handleClick = async () => { + let to = !liked + + setCliked(to) + + if (typeof props.onClick === "function") { + const result = await props.onClick(to) + if (typeof result === "boolean") { + to = result + } + } + + setLiked(to) + } + + return +} \ No newline at end of file diff --git a/packages/app/src/components/LikeButton/index.less b/packages/app/src/components/LikeButton/index.less new file mode 100644 index 00000000..fa9f9e08 --- /dev/null +++ b/packages/app/src/components/LikeButton/index.less @@ -0,0 +1,151 @@ +@color-heart : #EA442B; +@likeAnimationDuration : .5s; +@likeAnimationEasing : cubic-bezier(.7, 0, .3, 1); + +.likeButton { + display : flex; + align-items : center; + justify-content: center; + + .ripple, + .ripple:before, + .ripple:after { + position : relative; + box-sizing: border-box; + } + + font-size : 40px; + border : none; + border-radius: 50%; + width : 1em; + height : 1em; + padding : 0; + margin : 0; + outline : none; + z-index : 2; + transition : transform @likeAnimationDuration @likeAnimationEasing; + cursor : pointer; + + background-color: transparent; + + &:before { + z-index : -1; + content : ''; + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; + border-radius: inherit; + transition : inherit; + } + + &:after { + content : ''; + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; + border-radius: inherit; + z-index : -1; + } + + .heart { + position: relative; + + >path { + stroke-width: 2; + transition : fill @likeAnimationDuration @likeAnimationEasing; + stroke : currentColor; + fill : transparent; + } + + &.liked { + >path { + stroke: var(--primaryColor); + fill : var(--primaryColor); + } + } + + &.clicked { + animation: heart-bounce @likeAnimationDuration @likeAnimationEasing; + + @keyframes heart-bounce { + 40% { + transform: scale(0.7); + } + + 0%, + 80%, + 100% { + transform: scale(1); + } + } + } + + animation: none; + } + + .ripple { + position : absolute; + height : 1em; + width : 1em; + border-radius: 50%; + overflow : hidden; + z-index : 1; + + &:before { + content : ''; + position : absolute; + top : 0; + left : 0; + width : 100%; + height : 100%; + border : .4em solid var(--primaryColor); + border-radius: inherit; + transform : scale(0); + } + + &.clicked { + &:before { + animation: ripple-out @likeAnimationDuration @likeAnimationEasing; + } + } + + } +} + +@keyframes ripple-out { + from { + transform: scale(0); + } + + to { + transform: scale(5); + } +} + +@keyframes depress { + + from, + to { + transform: none; + } + + 50% { + transform: translateY(5%) scale(0.9); + } +} + +@keyframes depress-shadow { + + from, + to { + transform: none; + } + + 50% { + transform: scale(0.5); + } +} \ No newline at end of file diff --git a/packages/app/src/components/index.js b/packages/app/src/components/index.js index c04ee9a8..2109093e 100644 --- a/packages/app/src/components/index.js +++ b/packages/app/src/components/index.js @@ -22,6 +22,7 @@ export { default as Navigation } from "./Navigation" export { default as ImageUploader } from "./ImageUploader" export { default as ImageViewer } from "./ImageViewer" +export { default as LikeButton } from "./LikeButton" export { default as PostCard } from "./PostCard" export { default as PostCreator } from "./PostCreator"