forked from reactplay/react-play
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request reactplay#466 from ammaaraslam/main
Added New Play - React Gradients
- Loading branch information
Showing
6 changed files
with
307 additions
and
1 deletion.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import React, { useState } from "react"; | ||
import { SiTailwindcss, SiCss3 } from "react-icons/si"; | ||
import { BsFillTriangleFill } from "react-icons/bs"; | ||
import toast from "react-hot-toast"; | ||
import { debounce } from "lodash"; | ||
|
||
const GradientComponent = ({ index, name, css, tailwind, colors }) => { | ||
// Function to copy tailwind,css, color to clipboard.This function takes in 2 arguments. One is the text to be copied and the other is the message for the toast. | ||
// Note:- Initially, there were three functions that executed this task. Later, combined those functions into just one function(the below one) for better practice and efficiency. | ||
const copyCode = async (codeToCopy, message) => { | ||
await navigator.clipboard.writeText(codeToCopy); | ||
toast(`Copied ${message}`, { | ||
icon: "📋", | ||
style: { | ||
backgroundColor: "#010326", | ||
color: "#00f2fe", | ||
}, | ||
}); | ||
}; | ||
|
||
return ( | ||
// Gradient Component | ||
<div | ||
key={index} | ||
className="group relative h-72 w-[22.5rem] rounded-2xl transition-all duration-150 md:hover:scale-105 border-[6px] border-[#010326]" | ||
style={{ background: css }} | ||
> | ||
{/* component containing buttons to copy code, colors of the gradient */} | ||
<div className="absolute md:group-hover:flex md:hidden flex right-0 top-0 w-fit rounded-lg rounded-tl-none rounded-br-none bg-[#010326] transition-all duration-200 py-1 px-2 justify-center items-center border-2 border-[#010326]"> | ||
<GradientCopyButton | ||
handleOnClick={() => copyCode(tailwind, "TailwindCSS")} | ||
tooltipText="Copy TailwindCSS" | ||
> | ||
<SiTailwindcss /> | ||
</GradientCopyButton> | ||
<GradientCopyButton | ||
handleOnClick={() => copyCode(css, "CSS")} | ||
tooltipText="Copy CSS" | ||
> | ||
<SiCss3 /> | ||
</GradientCopyButton> | ||
{colors.map((color) => ( | ||
<GradientCopyButton | ||
handleOnClick={() => copyCode(color, "Color")} | ||
tooltipText="Copy Color" | ||
> | ||
<span className="text-sm uppercase font-semibold">{color}</span> | ||
</GradientCopyButton> | ||
))} | ||
</div> | ||
|
||
{/* Name of the gradient. Note:- Hoping to add a like button to this same component in the future with justify-between to evenly space the Name on the left and the like button on the right.*/} | ||
<div class="absolute bottom-0 w-full rounded-b-lg bg-[#010326] py-4 px-6 text-xl font-bold text-white"> | ||
{name} | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default GradientComponent; | ||
|
||
// This component is the button for copying the codes, color. Made it a separate component because it used several times and for easy customization. | ||
const GradientCopyButton = ({ children, handleOnClick, tooltipText }) => { | ||
// state variables for setting hover state of button. | ||
const [isHovered, setIsHovered] = useState(false); | ||
|
||
// onMouseEnter function that passes the event handler into lodash's debounce function to add a delay of 700s and sets setIsHovered to true. | ||
const handleOnMouseEnter = debounce(() => setIsHovered(true), 700); | ||
|
||
// onMouseLeave function that sets setIsHovered to false and calls the handleOnMouseEnter.cancel() to cancel the calling of the handleOnMouseEnter function. | ||
const handleOnMouesLeave = () => { | ||
setIsHovered(false); | ||
handleOnMouseEnter.cancel(); | ||
}; | ||
|
||
return ( | ||
<button | ||
className="flex p-2 text-gray-300 justify-center hover:text-white hover:bg-cyan-700 text-xl hover:bg-opacity-50 rounded-full transition-all duration-200" | ||
onClick={handleOnClick} | ||
onMouseEnter={handleOnMouseEnter} | ||
onMouseLeave={handleOnMouesLeave} | ||
> | ||
{children} | ||
{/* Logic that displays a tooltip when hovered. If state variable isHovered is true it is displayed, else it does not. */} | ||
{isHovered && ( | ||
<p className="absolute inline-flex justify-center z-50 mt-10 w-fit p-2 text-xs bg-cyan-700 rounded-xl"> | ||
<BsFillTriangleFill className="absolute -mt-3 text-cyan-700" /> | ||
{tooltipText} | ||
</p> | ||
)} | ||
</button> | ||
); | ||
}; |
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,63 @@ | ||
import PlayHeader from "common/playlists/PlayHeader"; | ||
import GradientComponent from "./GradientComponent"; | ||
import gradients from "./gradients.json"; | ||
import { IoColorPaletteSharp, IoAddSharp } from "react-icons/io5"; | ||
import { Toaster } from "react-hot-toast"; | ||
|
||
// WARNING: Do not change the entry componenet name | ||
function ReactGradients(props) { | ||
// Your Code Start below. | ||
|
||
return ( | ||
<> | ||
<div className="play-details"> | ||
<PlayHeader play={props} /> | ||
<div className="play-details-body"> | ||
{/* Header/Intro of play */} | ||
<div className="w-full h-fit py-11 px-7 text-center"> | ||
<span className="font-bold md:text-4xl text-3xl w-full text-black inline-flex justify-center items-center"> | ||
React | ||
<IoColorPaletteSharp | ||
className="text-[#00f2fe] mt-auto mb-auto" | ||
size={50} | ||
/> | ||
Gradients | ||
</span> | ||
<p className="mt-2 font-semibold md:text-xl text-lg w-full text-gray-700"> | ||
A collection of beautiful gradients that you can copy to easily | ||
use in your application. | ||
</p> | ||
</div> | ||
|
||
{/* Grid layout of all gradients */} | ||
<div className="grid py-2 md:px-6 px-4 lg:grid-cols-3 md:grid-cols-2 grid-cols-1 gap-8 place-items-center"> | ||
{gradients.map((gradient, index) => ( | ||
<GradientComponent | ||
index={index} | ||
name={gradient.name} | ||
css={gradient.css} | ||
tailwind={gradient.tailwind} | ||
colors={gradient.colors} | ||
/> | ||
))} | ||
</div> | ||
|
||
{/* Button to add new gradient, Note:- Currently it is an <a> tag that redirects to README.md of the play. Hoping to convert it to a <button> element that opens up a modal containing a form to easily add a gradient. */} | ||
<a | ||
href="/reactplay/react-play/src/plays/react-gradients#contributing" | ||
target="_blank" | ||
rel="noreferrer" | ||
className="fixed bottom-16 md:right-9 right-7 w-fit p-4 text-white bg-[#00f2fe] rounded-full font-semibold text-xl inline-flex justify-center items-center border-2 border-[#00f2fe] hover:bg-white hover:text-[#00f2fe] transition-all duration-200" | ||
> | ||
<IoAddSharp size={32} />{" "} | ||
<span className="md:flex hidden ml-2">Add a Gradient</span> | ||
</a> | ||
{/* react-hot-toast component to display a message when code/color is copied */} | ||
<Toaster position="bottom-left" reverseOrder={false} /> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
export default ReactGradients; |
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,75 @@ | ||
# React Gradients | ||
|
||
React Gradients is list of beautiful gradients which you can easily use for your application by copying the CSS/TailwindCSS code for the desired gradient. You can also copy each color that has been used in the gradient. | ||
|
||
## Play Demographic | ||
|
||
- Language: js | ||
- Level: Intermediate | ||
|
||
## Creator Information | ||
|
||
- User: ammaaraslam | ||
- Gihub Link: https://github.com/ammaaraslam | ||
|
||
## Implementation Details | ||
|
||
The implementation of the play is fairly simple. | ||
- Firstly it consumes data *(list of gradients and its details)* from a `json` file called `gradients.json`. | ||
- Then it uses the `.map()` function to loop through this data and get each object *(gradient)*. | ||
- Each object/gradient has the following properties: | ||
- `name` - The Name of the gradient | ||
- `tailwind` - The TailwindCSS code for the gradient. | ||
- `css` - The CSS code for the gradient. | ||
- `colors` - A list of colors used in the gradient. | ||
- The properties of each gradient is passed to the separate component named `GradientComponent` in the `GradientComponent.js` file to be styled and displayed. | ||
- In the `GradientComponent` component, you will find the following function: | ||
- `copyCode` - This function is used to copy the tailwind, css, color of a gradient to the clipboard. This function **takes in 2 arguments**. | ||
1. `codeToCopy` - The text that needs to be copied. | ||
2. `message` - The message to be displayed in the toast. *(If user clicked to copy the TailwindCSS code, the message argument is "TailwindCSS". Then the toast says "Copied TailwindCSS")* | ||
- >**Note:-** Initially, there were three different functions(`copyTailwind`, `copyCSS`, `copyColor`) to copy. Later combined these functions into one, the `copyCode` function for better practice and efficiency. | ||
- Also in the `GradientComponent` component, you will find a `GradientCopyButton` component. This is a button component for copying the different TailwindCSS, CSS and color codes. It also displays a tooltip on hover. This tooltip is achieved by using react useState hook, `debounce` function of `lodash` to set delay on hover and onMouseEnter,onMouseLeave events to set the state of a state variable. Then the tooltip is conditionally displayed using that state variable. | ||
- And finally, the play uses `react-hot-toast` *(a notification library for react)* to display a message after user has copied. | ||
|
||
## Contributing | ||
|
||
First of all thanks for wanting to contribute! To start contributing to this play, please go through the [Contribution guidelines of ReactPlay](https://github.com/reactplay/react-play/blob/main/CONTRIBUTING.md). | ||
|
||
### Adding a new gradient | ||
|
||
Currently to add a new gradient, you'll have to create a new `json` object in the `gradients.json` file. To do so, please follow the below steps. | ||
- In the `gradients.json` file, add a new gradient of choice using the following syntax: | ||
```json | ||
{ | ||
"name": "Name of the Gradient", | ||
"css": "CSS code for the gradient.", | ||
"tailwind": "TailwindCSS code for the gradient", | ||
"colors": ["A list containing all the colors used in the gradient"] | ||
}, | ||
``` | ||
**Example**: | ||
```json | ||
{ | ||
"name": "Flamingo", | ||
"css": "linear-gradient(to right, #f472b6, #db2777)", | ||
"tailwind": "bg-gradient-to-r from-pink-400 to-pink-600", | ||
"colors": ["#f472b6", "#db2777"] | ||
}, | ||
``` | ||
- Then create a Pull Request referencing this play. | ||
> **Note:-** Please make sure to add all your colors in the form of HEX. Please use [this converter](https://www.w3schools.com/colors/colors_converter.asp) if you have used any other format. | ||
|
||
>**Also Note:-** In the future, I'm hoping to add a feature where you are able to add a gradient easily by filling a simple form directly from the play so that you don't have to go through the trouble of doing everything manually, so stay tuned for that! | ||
|
||
## Resources | ||
|
||
Learn more about `react-hot-toast` -https://react-hot-toast.com/docs | ||
|
||
Learn more about `JSON` Objects - https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects/JSON | ||
|
||
|
||
## Thanks for your time! | ||
|
||
Thank you so much for taking the time to read this. If you like this play, please do share about it and tag me [@itsammaar_7](https://twitter.com/itsammaar_7) and [@ReactPlayIO](https://twitter.com/ReactPlayIO). Also star the [react-play repository](https://github.com/reactplay/react-play), it gives me and all the [contributors](https://github.com/reactplay/react-play#contributors-) a boost in confidence 🤩. | ||
|
||
**Happy Coding!!** |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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,74 @@ | ||
[ | ||
{ | ||
"name": "Emerald", | ||
"css": "linear-gradient(to right, #10b981, #65a30d)", | ||
"tailwind": "bg-gradient-to-r from-emerald-500 to-lime-600", | ||
"colors": ["#10b981", "#65a30d"] | ||
}, | ||
{ | ||
"name": "Horizon", | ||
"css": "linear-gradient(#f97316, #fde047)", | ||
"tailwind": "bg-gradient-to-b from-orange-500 to-yellow-300", | ||
"colors": ["#f97316", "#fde047"] | ||
}, | ||
{ | ||
"name": "Green Apple", | ||
"css": "linear-gradient(to right, #22c55e, #15803d)", | ||
"tailwind": "bg-gradient-to-r from-green-500 to-green-700", | ||
"colors": ["#22c55e", "#15803d"] | ||
}, | ||
{ | ||
"name": "Deep Blue", | ||
"css": "linear-gradient(to right, #2563eb, #1e40af, #1e3a8a)", | ||
"tailwind": "bg-gradient-to-r from-blue-600 via-blue-800 to-blue-900", | ||
"colors": ["#2563eb", "#1e40af", "#1e3a8a"] | ||
}, | ||
{ | ||
"name": "Dawn", | ||
"css": "linear-gradient(to right, #fb7185, #fdba74)", | ||
"tailwind": "bg-gradient-to-r from-rose-400 to-orange-300", | ||
"colors": ["#fb7185", "#fdba74"] | ||
}, | ||
{ | ||
"name": "Midnight", | ||
"css": "linear-gradient(to right, #1d4ed8, #1e40af, #111827)", | ||
"tailwind": "bg-gradient-to-r from-blue-700 via-blue-800 to-gray-900", | ||
"colors": ["#1d4ed8", "#1e40af", "#111827"] | ||
}, | ||
{ | ||
"name": "Coral", | ||
"css": "linear-gradient(to right, #60a5fa, #34d399)", | ||
"tailwind": "bg-gradient-to-r from-blue-400 to-emerald-400", | ||
"colors": ["#60a5fa", "#34d399"] | ||
}, | ||
{ | ||
"name": "Flamingo", | ||
"css": "linear-gradient(to right, #f472b6, #db2777)", | ||
"tailwind": "bg-gradient-to-r from-pink-400 to-pink-600", | ||
"colors": ["#f472b6", "#db2777"] | ||
}, | ||
{ | ||
"name": "Ocean", | ||
"css": "linear-gradient(to right, #a5f3fc, #22d3ee)", | ||
"tailwind": "bg-gradient-to-r from-cyan-200 to-cyan-400", | ||
"colors": ["#a5f3fc", "#22d3ee"] | ||
}, | ||
{ | ||
"name": "Metal", | ||
"css": "conic-gradient(at right center, #c7d2fe, #475569, #c7d2fe)", | ||
"tailwind": "bg-conic-to-r from-indigo-200 via-slate-600 to-indigo-200", | ||
"colors": ["#c7d2fe", "#475569", "#c7d2fe"] | ||
}, | ||
{ | ||
"name": "Green Galaxy", | ||
"css": "radial-gradient(at left center, #06b6d4, #047857, #dbeafe)", | ||
"tailwind": "bg-radial-at-l from-cyan-500 via-emerald-700 to-blue-100", | ||
"colors": ["#06b6d4", "#047857", "#dbeafe"] | ||
}, | ||
{ | ||
"name": "Pure Blue Shade", | ||
"css": "conic-gradient(at left top, #14b8a6, #4338ca, #1f2937)", | ||
"tailwind": "bg-conic-to-tl from-teal-500 via-indigo-700 to-gray-800", | ||
"colors": ["#14b8a6", "#4338ca", "#1f2937"] | ||
} | ||
] |