├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.png └── index.html └── src ├── App.css ├── App.js ├── Components ├── Details │ ├── Details.css │ └── Details.jsx ├── Editor │ ├── Editor.css │ ├── Editor.jsx │ └── assets │ │ └── star.png ├── Navbar │ ├── Navbar.css │ └── Navbar.jsx └── Options │ ├── Options.css │ ├── Options.jsx │ └── assets │ ├── headset.png │ ├── headset_on.png │ ├── star.png │ ├── trash.png │ └── volume.png ├── index.css └── index.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | 3 |

The minimalistic Text Editr.

4 | 5 | ## Features 🚀 6 | 7 | - Minimal User Interface 8 | - Text Statistics 9 | - Voice Recognition 10 | - Microphone Statistics 11 | - Basic Functions 12 | - Easy to Use 13 | - Optimised User Experience 14 | 15 | ## Tech Stack 🖥️ 16 | 17 | - HTML 18 | - CSS 19 | - JavaScript 20 | - React.js 21 | - Made using Pure CSS 22 | 23 | ## Modules 🖱️ 24 | 25 | - react-speech-recognition: React speech recognition is used to recognition the user's microphone input and display it onto the text editor. 26 | - react-confirm-alert: React confirm alert is used to show the confirm dialog box which the user click the trash button on the bottom options menu. 27 | 28 | ## About Me 🦸 29 | 30 | - [LinkedIn](https://www.linkedin.com/in/-aswinasok/) 31 | - [Twitter](https://twitter.com/_aswin_asok_) 32 | - [Instagram](https://www.instagram.com/_aswin_asok_/) 33 | 34 | ## Checkout [Editr.](https://editr.netlify.app) Now ! [![Netlify Status](https://api.netlify.com/api/v1/badges/35eab099-4b80-449e-939e-27a7927cbba2/deploy-status)](https://app.netlify.com/sites/editr/deploys) 35 | 36 | ### Liked the Project, Support Me by Giving Editr a 🌟 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "editr", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@speechly/speech-recognition-polyfill": "^1.1.0", 7 | "@testing-library/jest-dom": "^5.16.2", 8 | "@testing-library/react": "^12.1.3", 9 | "@testing-library/user-event": "^13.5.0", 10 | "react": "^17.0.2", 11 | "react-confirm-alert": "^2.8.0", 12 | "react-dom": "^17.0.2", 13 | "react-scripts": "5.0.0", 14 | "react-speech-recognition": "^3.9.0", 15 | "web-vitals": "^2.1.4" 16 | }, 17 | "scripts": { 18 | "start": "react-scripts start", 19 | "build": "react-scripts build", 20 | "test": "react-scripts test", 21 | "eject": "react-scripts eject" 22 | }, 23 | "eslintConfig": { 24 | "extends": [ 25 | "react-app", 26 | "react-app/jest" 27 | ] 28 | }, 29 | "browserslist": { 30 | "production": [ 31 | ">0.2%", 32 | "not dead", 33 | "not op_mini all" 34 | ], 35 | "development": [ 36 | "last 1 chrome version", 37 | "last 1 firefox version", 38 | "last 1 safari version" 39 | ] 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/public/favicon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | Editr. 14 | 15 | 16 |
17 | 18 | 19 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin: 0; 3 | padding: 0; 4 | } 5 | 6 | .App { 7 | position: relative; 8 | min-height: 100vh; 9 | padding-bottom: 15vh; 10 | background-color: #ffffff; 11 | background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='100' height='100' viewBox='0 0 100 100'%3E%3Cg fill-rule='evenodd'%3E%3Cg fill='%23d198fe' fill-opacity='0.4'%3E%3Cpath opacity='.5' d='M96 95h4v1h-4v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4h-9v4h-1v-4H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15v-9H0v-1h15V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h9V0h1v15h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9h4v1h-4v9zm-1 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm9-10v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-10 0v-9h-9v9h9zm-9-10h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9zm10 0h9v-9h-9v9z'/%3E%3Cpath d='M6 5V0H5v5H0v1h5v94h1V6h94V5H6z'/%3E%3C/g%3E%3C/g%3E%3C/svg%3E"); 12 | } 13 | 14 | .main-container { 15 | margin-top: 5vh; 16 | display: flex; 17 | flex-direction: column; 18 | align-items: center; 19 | } 20 | 21 | @media only screen and (min-width: 1000px) { 22 | .main-container { 23 | flex-direction: row; 24 | justify-content: space-evenly; 25 | align-items: flex-start; 26 | } 27 | 28 | .App { 29 | padding-bottom: 0; 30 | } 31 | } 32 | 33 | .buttons { 34 | margin-top: 3vh; 35 | display: flex; 36 | width: 80vw; 37 | margin-left: 10vw; 38 | flex-direction: column; 39 | justify-content: center; 40 | align-items: center; 41 | } 42 | 43 | .pribtn { 44 | font-family: "Montserrat Alternates", sans-serif; 45 | margin: 0.5rem; 46 | font-weight: 500; 47 | background-color: #940eff; 48 | color: white; 49 | padding: 0.4rem 3rem; 50 | border: none; 51 | font-size: 1.15rem; 52 | border-radius: 5px; 53 | display: flex; 54 | justify-content: center; 55 | align-items: center; 56 | 57 | cursor: pointer; 58 | user-select: none; 59 | text-align: center; 60 | text-decoration: none; 61 | cursor: pointer; 62 | transition-duration: 0.4s; 63 | -webkit-transition-duration: 0.4s; /* Safari */ 64 | } 65 | 66 | .pribtn:hover { 67 | transition-duration: 0.1s; 68 | background-color: #3a3a3a; 69 | } 70 | 71 | .secbtn:hover { 72 | transition-duration: 0.1s; 73 | color: #3a3a3a; 74 | border: 2px solid #3a3a3a; 75 | } 76 | 77 | .pribtn i, 78 | .secbtn i { 79 | margin-left: 0.5rem; 80 | font-size: 1.95rem; 81 | padding-top: 0.5vh; 82 | } 83 | 84 | .secbtn { 85 | border-radius: 5px; 86 | font-family: "Montserrat Alternates", sans-serif; 87 | margin: 0.5rem; 88 | font-weight: 500; 89 | color: #940eff; 90 | border: 2px solid #940eff; 91 | background-color: white; 92 | padding: 0.4rem 3rem; 93 | font-size: 1.15rem; 94 | display: flex; 95 | justify-content: center; 96 | align-items: center; 97 | } 98 | 99 | @media only screen and (min-width: 1000px) { 100 | .buttons { 101 | margin-top: 1vh; 102 | display: flex; 103 | flex-direction: row; 104 | justify-content: center; 105 | width: auto; 106 | margin-left: 0vw; 107 | } 108 | } 109 | 110 | 111 | .prod-hunt{ 112 | height: 3.75rem; 113 | } 114 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import "./App.css"; 2 | import Navbar from "./Components/Navbar/Navbar.jsx"; 3 | import Editor from "./Components/Editor/Editor.jsx"; 4 | import Options from "./Components/Options/Options.jsx"; 5 | import Details from "./Components/Details/Details"; 6 | 7 | import { useEffect, useState } from "react"; 8 | import SpeechRecognition, { 9 | useSpeechRecognition, 10 | } from "react-speech-recognition"; 11 | 12 | import { createSpeechlySpeechRecognition } from "@speechly/speech-recognition-polyfill"; 13 | 14 | const appId = process.env.REACT_APP_APP_ID; 15 | const SpeechlySpeechRecognition = createSpeechlySpeechRecognition(appId); 16 | SpeechRecognition.applyPolyfill(SpeechlySpeechRecognition); 17 | 18 | function App() { 19 | const [text, setText] = useState(""); 20 | const [words, setWords] = useState(0); 21 | const [characters, setCharacters] = useState(0); 22 | const [special, setSpecial] = useState(0); 23 | const [stars, setStars] = useState(0); 24 | let format = /[!@#$%^&*()_+\-=\[\]{};':"\\|,.<>\/?]+/; 25 | let localcount = 0; 26 | 27 | const { transcript, listening, browserSupportsSpeechRecognition } = 28 | useSpeechRecognition(); 29 | const startListening = () => 30 | SpeechRecognition.startListening({ continuous: true }); 31 | 32 | useEffect(() => { 33 | if (text) { 34 | setCharacters(text.length); 35 | setWords(text.split(" ").length); 36 | 37 | for (let index = 0; index < text.length; index++) { 38 | if (format.test(text.charAt(index))) { 39 | localcount += 1; 40 | } 41 | } 42 | setSpecial(localcount); 43 | } else { 44 | setCharacters(0); 45 | setWords(0); 46 | setSpecial(0); 47 | } 48 | }, [text]); 49 | 50 | useEffect(() => { 51 | if (transcript.length > 0 && text.length > 0) { 52 | setText(text + " " + transcript.toLowerCase()); 53 | } else if (transcript.length > 0) { 54 | setText(transcript.toLowerCase()); 55 | } 56 | }, [listening]); 57 | 58 | useEffect(async () => { 59 | fetch(`https://api.github.com/repos/AswinAsok/text.ly`) 60 | .then((res) => res.json()) 61 | .then((data) => { 62 | setStars(data.stargazers_count); 63 | }); 64 | }, []); 65 | 66 | return ( 67 |
68 | 69 |
70 | 71 |
78 |
79 |
80 | 81 | 84 | 85 | 86 | 87 | 90 | 91 | 92 | 96 | Editr - Minimalistic text editor | Product Hunt 101 | 102 |
103 | 104 | 105 |
106 | ); 107 | } 108 | 109 | export default App; 110 | -------------------------------------------------------------------------------- /src/Components/Details/Details.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Montserrat+Alternates:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800&display=swap"); 2 | 3 | .details-container { 4 | background-color: white; 5 | margin-top: 2vh; 6 | } 7 | 8 | .details { 9 | width: 80vw; 10 | font-family: "Poppins", sans-serif; 11 | box-shadow: 0px 0.7px 11.5px rgba(0, 0, 0, 0.028), 12 | 0px 2.2px 38.6px rgba(0, 0, 0, 0.042), 0px 10px 173px rgba(0, 0, 0, 0.07); 13 | border: 2px solid #940eff; 14 | border-radius: 5px; 15 | padding: 1.5rem; 16 | display: flex; 17 | flex-direction: column; 18 | justify-content: space-evenly; 19 | } 20 | 21 | .heading { 22 | font-family: "Poppins", sans-serif; 23 | font-weight: 600; 24 | font-size: 1.5rem; 25 | margin-bottom: 1vh; 26 | text-align: center; 27 | color: #404040; 28 | } 29 | 30 | @media only screen and (min-width: 1000px) { 31 | .details-container { 32 | margin-top: 0; 33 | } 34 | 35 | .details { 36 | width: 25vw; 37 | height: 50vh; 38 | } 39 | } 40 | 41 | .counters-container { 42 | display: flex; 43 | justify-content: center; 44 | } 45 | 46 | .count { 47 | display: flex; 48 | flex-direction: column; 49 | align-items: center; 50 | margin: 0.5rem; 51 | } 52 | 53 | .counter { 54 | font-size: 1.25rem; 55 | color: #404040; 56 | font-weight: 600; 57 | } 58 | 59 | .label { 60 | margin-top: 1vh; 61 | margin-left: 0.5rem; 62 | font-size: 1rem; 63 | font-weight: 500; 64 | color: #3a3a3a; 65 | text-align: center; 66 | font-family: "Montserrat Alternates"; 67 | } 68 | 69 | .circle { 70 | display: flex; 71 | align-items: center; 72 | justify-content: center; 73 | width: 2.5rem; 74 | height: 2.5rem; 75 | border-radius: 50%; 76 | border: 2px solid #940eff; 77 | box-shadow: 0px 0.7px 11.5px rgba(0, 0, 0, 0.028), 78 | 0px 2.2px 38.6px rgba(0, 0, 0, 0.042), 0px 10px 173px rgba(0, 0, 0, 0.07); 79 | } 80 | 81 | .microphone-container { 82 | margin-top: 2vh; 83 | } 84 | 85 | .indicators { 86 | display: flex; 87 | flex-direction: row; 88 | justify-content: center; 89 | align-items: center; 90 | } 91 | 92 | .on, 93 | .off, 94 | .listening { 95 | display: flex; 96 | flex-direction: column; 97 | align-items: center; 98 | justify-content: center; 99 | margin: 1rem; 100 | } 101 | 102 | .indicator { 103 | width: 1rem; 104 | height: 1rem; 105 | transition-duration: 0.1s; 106 | background-color: #3a3a3a; 107 | border-radius: 50%; 108 | margin-bottom: 1vh; 109 | } 110 | 111 | .working { 112 | transition-duration: 0.1s; 113 | background-color: #4ceb94; 114 | } 115 | 116 | .nospeech { 117 | text-align: center; 118 | color: rgb(235, 82, 82); 119 | } 120 | 121 | .nospeech span { 122 | font-weight: 500; 123 | } 124 | -------------------------------------------------------------------------------- /src/Components/Details/Details.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./Details.css"; 3 | 4 | const Details = ({ 5 | words, 6 | characters, 7 | special, 8 | listening, 9 | browserSupportsSpeechRecognition, 10 | }) => { 11 | return ( 12 |
13 |
14 |
15 |

Editr Statistics

16 |
17 |
18 |
19 |

{words}

20 |
21 |

Words

22 |
23 | 24 |
25 |
26 |

{special}

27 |
28 |

Special Characters

29 |
30 | 31 |
32 |
33 |

{characters}

34 |
35 |

Characters

36 |
37 |
38 |
39 | 40 |
41 |

Microphone Input Status

42 | {(() => { 43 | if (!browserSupportsSpeechRecognition) { 44 | return ( 45 |

46 | This browser doesn't support
47 | Speech Recognition !. 48 |

49 | ); 50 | } else if (!listening) { 51 | return ( 52 |
53 |
54 |
Mic On 55 |
56 | 57 |
58 |
Listening.. 59 |
60 | 61 |
62 |
Mic Off 63 |
64 |
65 | ); 66 | } else { 67 | return ( 68 |
69 |
70 |
Mic On 71 |
72 | 73 |
74 |
Listening.. 75 |
76 | 77 |
78 |
Mic Off 79 |
80 |
81 | ); 82 | } 83 | })()} 84 |
85 |
86 |
87 | ); 88 | }; 89 | 90 | export default Details; 91 | -------------------------------------------------------------------------------- /src/Components/Editor/Editor.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Montserrat+Alternates:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600&family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800&display=swap"); 2 | @import url("https://cdn-uicons.flaticon.com/uicons-brands/css/uicons-brands.css"); 3 | 4 | .textarea { 5 | width: 80vw; 6 | height: 50vh; 7 | font-family: "Poppins", sans-serif; 8 | font-weight: 400; 9 | font-size: 1rem; 10 | padding: 1.5rem; 11 | text-align: start; 12 | box-shadow: 0px 0.7px 11.5px rgba(0, 0, 0, 0.028), 13 | 0px 2.2px 38.6px rgba(0, 0, 0, 0.042), 0px 10px 173px rgba(0, 0, 0, 0.07); 14 | border: 2px solid #940eff; 15 | border-radius: 5px; 16 | } 17 | 18 | @media only screen and (min-width: 1000px) { 19 | .textarea { 20 | width: 60vw; 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /src/Components/Editor/Editor.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./Editor.css"; 3 | 4 | const Editor = ({ text, setText, stars }) => { 5 | return ( 6 |
7 |
8 | 17 |
18 |
19 | ); 20 | }; 21 | 22 | export default Editor; 23 | -------------------------------------------------------------------------------- /src/Components/Editor/assets/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/src/Components/Editor/assets/star.png -------------------------------------------------------------------------------- /src/Components/Navbar/Navbar.css: -------------------------------------------------------------------------------- 1 | @import url("https://fonts.googleapis.com/css2?family=Montserrat+Alternates:ital,wght@0,300;0,400;0,500;0,600;0,700;1,300;1,400;1,500;1,600&display=swap"); 2 | @import url("https://cdn-uicons.flaticon.com/uicons-brands/css/uicons-brands.css"); 3 | 4 | .navbar-container { 5 | font-family: "Montserrat Alternates", sans-serif; 6 | font-weight: 600; 7 | font-size: 1.5rem; 8 | background-color: #940eff; 9 | color: white; 10 | text-align: center; 11 | padding: 0.75rem; 12 | } 13 | 14 | .tagline { 15 | font-size: 0.8rem; 16 | margin-top: 0.25vh; 17 | } 18 | 19 | .nav-btns { 20 | display: none; 21 | } 22 | 23 | @media only screen and (min-width: 1000px) { 24 | .navbar-container { 25 | display: flex; 26 | flex-direction: row; 27 | justify-content: space-between; 28 | padding: 0.75rem 2.5rem; 29 | text-align: left; 30 | font-size: 2rem; 31 | } 32 | .nav-btns { 33 | display: flex; 34 | } 35 | 36 | .nbtn { 37 | background-color: white; 38 | font-size: 1rem; 39 | border: none; 40 | padding: 0.4rem 1.2rem; 41 | margin: 0 0.5rem; 42 | border-radius: 5px; 43 | color: #940eff; 44 | border: 2px solid #940eff; 45 | font-family: "Montserrat Alternates", sans-serif; 46 | font-weight: 500; 47 | display: flex; 48 | flex-direction: row; 49 | align-items: center; 50 | justify-content: center; 51 | } 52 | 53 | .nbtn:hover { 54 | transition-duration: 0.1s; 55 | color: #3a3a3a; 56 | border: 2px solid #3a3a3a; 57 | } 58 | 59 | .nbtn i { 60 | margin-left: 0.5rem; 61 | font-size: 1.55rem; 62 | padding-top: 0.5vh; 63 | color: #940eff; 64 | } 65 | 66 | .nbtn i:hover { 67 | color: #3a3a3a; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/Components/Navbar/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import "./Navbar.css"; 3 | 4 | const Navbar = () => { 5 | return ( 6 |
7 |
8 |
9 |

Editr.

10 |

The Minimal Text Editr

11 |
12 |
13 | 14 | 17 | 18 | 19 | 22 | 23 |
24 |
25 |
26 | ); 27 | }; 28 | 29 | export default Navbar; 30 | -------------------------------------------------------------------------------- /src/Components/Options/Options.css: -------------------------------------------------------------------------------- 1 | @import url("https://cdn-uicons.flaticon.com/uicons-regular-rounded/css/uicons-regular-rounded.css"); 2 | @import url("https://cdn-uicons.flaticon.com/uicons-solid-rounded/css/uicons-solid-rounded.css"); 3 | 4 | a { 5 | text-decoration: none; 6 | } 7 | 8 | .options-container { 9 | position: fixed; 10 | bottom: 0; 11 | left: 50%; 12 | transform: translate(-50%, -50%); 13 | } 14 | 15 | .options { 16 | box-shadow: 0px 0.7px 11.5px rgba(0, 0, 0, 0.028), 17 | 0px 2.2px 38.6px rgba(0, 0, 0, 0.042), 0px 10px 173px rgba(0, 0, 0, 0.07); 18 | background-color: white; 19 | bottom: 0; 20 | border: 2px solid #940eff; 21 | border-radius: 10px; 22 | padding-top: 0.5rem; 23 | } 24 | 25 | .option { 26 | margin: 1rem; 27 | font-size: 1.95rem; 28 | color: #940eff; 29 | } 30 | 31 | .option:hover { 32 | color: #3a3a3a; 33 | } 34 | 35 | .mheading { 36 | font-size: 1.5rem; 37 | font-family: "Montserrat Alternates", sans-serif; 38 | font-weight: bold; 39 | } 40 | 41 | .mtagline { 42 | font-family: "Poppins", sans-serif; 43 | margin-top: 1vh; 44 | } 45 | 46 | .mbtns { 47 | margin-top: 2vh; 48 | } 49 | 50 | .mno, 51 | .myes { 52 | margin-right: 0.5rem; 53 | font-size: 1.05rem; 54 | padding: 0.25rem 0.75rem; 55 | } 56 | 57 | .mno { 58 | background-color: #940eff; 59 | color: white; 60 | border: none; 61 | font-family: "Poppins", sans-serif; 62 | border-radius: 5px; 63 | } 64 | 65 | .myes { 66 | border: 2px solid #940eff; 67 | color: #940eff; 68 | background-color: white; 69 | border-radius: 5px; 70 | font-family: "Poppins", sans-serif; 71 | } 72 | -------------------------------------------------------------------------------- /src/Components/Options/Options.jsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | import "./Options.css"; 3 | 4 | import ReactConfirmAlert, { confirmAlert } from "react-confirm-alert"; 5 | import "react-confirm-alert/src/react-confirm-alert.css"; 6 | 7 | import SpeechRecognition from "react-speech-recognition"; 8 | 9 | const Options = ({ setText, listening, text }) => { 10 | const [showDialog, setShowDialog] = useState(false); 11 | return ( 12 | <> 13 |
14 |
15 | {(() => { 16 | if (!listening) { 17 | return ( 18 | 23 | ); 24 | } else { 25 | return ( 26 | 30 | ); 31 | } 32 | })()} 33 | 34 | { 38 | if (text.length > 0) { 39 | setShowDialog(true); 40 | } 41 | }} 42 | > 43 | 44 | 45 | 46 |
47 |
48 | 49 |
50 | {text.length > 0 && 51 | showDialog && 52 | confirmAlert({ 53 | customUI: ({ onClose }) => { 54 | return ( 55 |
56 |

Are you sure?

57 |

You want to delete this Text?

58 |
59 | 62 | 72 |
73 |
74 | ); 75 | }, 76 | })} 77 |
78 | 79 | ); 80 | }; 81 | 82 | export default Options; 83 | -------------------------------------------------------------------------------- /src/Components/Options/assets/headset.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/src/Components/Options/assets/headset.png -------------------------------------------------------------------------------- /src/Components/Options/assets/headset_on.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/src/Components/Options/assets/headset_on.png -------------------------------------------------------------------------------- /src/Components/Options/assets/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/src/Components/Options/assets/star.png -------------------------------------------------------------------------------- /src/Components/Options/assets/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/src/Components/Options/assets/trash.png -------------------------------------------------------------------------------- /src/Components/Options/assets/volume.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/src/Components/Options/assets/volume.png -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AswinAsok/editr/8743e4069304bf4f62cce7e416eab9766f61675a/src/index.css -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | 6 | ReactDOM.render( 7 | 8 | 9 | , 10 | document.getElementById('root') 11 | ); 12 | 13 | --------------------------------------------------------------------------------