diff options
Diffstat (limited to 'client/src')
-rw-r--r-- | client/src/components/Editor/Editor.jsx | 20 | ||||
-rw-r--r-- | client/src/components/ToolTip/ToolTip.jsx | 60 | ||||
-rw-r--r-- | client/src/components/ToolTip/ToolTip.module.css | 64 | ||||
-rw-r--r-- | client/src/variables.css | 1 |
4 files changed, 144 insertions, 1 deletions
diff --git a/client/src/components/Editor/Editor.jsx b/client/src/components/Editor/Editor.jsx index 976c1b2..304da68 100644 --- a/client/src/components/Editor/Editor.jsx +++ b/client/src/components/Editor/Editor.jsx @@ -23,6 +23,7 @@ import Modal from "../Modal/Modal"; import AlertToast from "../AlertToast/AlertToast"; import CustomSelect from "../CustomSelect/CustomSelect"; import KeyboardModal from "../KeyboardModal/KeyboardModal"; +import ToolTip from "../ToolTip/ToolTip"; const Editor = () => { const { id } = useParams(); @@ -33,6 +34,7 @@ const Editor = () => { const [openModal, setOpenModal] = useState(false); const [openKeyboardModal, setOpenKeyboardModal] = useState(false); const [openAlertToast, setOpenAlertToast] = useState(false); + const [isToolTipShown, setIsToolTipShown] = useState(false); const textareaRef = useRef(null); const lineNumberRef = useRef(null); const queryParams = useMemo( @@ -144,6 +146,17 @@ const Editor = () => { Prism.highlightAll(); }, [text, language]); + useEffect(() => { + const isToolTipShown = localStorage.getItem("isToolTipShown"); + if (!isToolTipShown) { + localStorage.setItem("isToolTipShown", "true"); + setIsToolTipShown(true); + } + if (textareaRef.current) { + textareaRef.current.focus(); + } + }, []); + const fetchData = useCallback(async () => { const response = await fetch(`${origin}/bin/${id}`); const data = await response.json(); @@ -211,6 +224,13 @@ const Editor = () => { return ( <> + {isToolTipShown && ( + <ToolTip + textAreaRef={textareaRef} + isOpen={isToolTipShown} + setIsOpen={setIsToolTipShown} + /> + )} {!id && ( <> <KeyboardModal diff --git a/client/src/components/ToolTip/ToolTip.jsx b/client/src/components/ToolTip/ToolTip.jsx new file mode 100644 index 0000000..993fa16 --- /dev/null +++ b/client/src/components/ToolTip/ToolTip.jsx @@ -0,0 +1,60 @@ +import React, { useRef, useState, useEffect } from "react"; +import styles from "./ToolTip.module.css"; + +const ToolTip = ({ isOpen, setIsOpen, textAreaRef }) => { + const toolTipRef = useRef(null); + + const handleClickOutside = (event) => { + if (toolTipRef.current && !toolTipRef.current.contains(event.target)) { + setIsOpen(false); + } + }; + + const handleKeyDown = (event) => { + if ( + isOpen && + (event.key === "Escape" || + (event.ctrlKey && (event.key === "k" || event.key === "l"))) + ) { + setIsOpen(false); + if (textAreaRef.current) { + textAreaRef.current.focus(); + } + } + }; + + useEffect(() => { + document.addEventListener("mousedown", handleClickOutside); + document.addEventListener("keydown", handleKeyDown); + return () => { + document.removeEventListener("mousedown", handleClickOutside); + document.removeEventListener("keydown", handleKeyDown); + }; + }, [isOpen]); + + return ( + isOpen && ( + <div ref={toolTipRef} className={`${styles.container} ${styles.active}`}> + <img + className={styles.container__triangle} + src="/assets/icons/triangle.png" + /> + <div className={styles.container__content}> + <p className={styles.container__title}>Keyboard Shortcuts</p> + <p className={styles.container__text}> + Press <span className={styles.container__key}>Ctrl+K</span> to view + keyboard shortcuts. + </p> + <span + className={styles.container__btn} + onClick={() => setIsOpen(false)} + > + Close + </span> + </div> + </div> + ) + ); +}; + +export default ToolTip; diff --git a/client/src/components/ToolTip/ToolTip.module.css b/client/src/components/ToolTip/ToolTip.module.css new file mode 100644 index 0000000..295968c --- /dev/null +++ b/client/src/components/ToolTip/ToolTip.module.css @@ -0,0 +1,64 @@ +.container { + display: none; + position: absolute; + top: 70px; + right: 20px; + z-index: 10; + width: 250px; + z-index: 11; + color: var(--color-dark); +} + +.container__triangle { + display: inline-block; + height: 1rem; + width: 1rem; + margin-right: 25px; + margin-bottom: -4px; + z-index: 1000; +} + +.container__content { + background-color: var(--color-yellow); + padding: 25px; + border-radius: 10px; + width: 250px; +} + +.container__text { + margin: 10px 0; +} + +.container__key { + font-weight: 500; +} + +.active { + display: flex; + flex-direction: column; + align-items: end; +} + +.container__title { + margin: 0; + font-weight: 500; + font-size: 1.15rem; +} + +.container__btn { + cursor: pointer; + color: #282828; + font-size: 1rem; + font-weight: 500; + transition: all 0.3s ease; + &:hover { + font-size: 0.9rem; + } +} + +@media screen and (max-width: 768px) { + .container, + .active { + display: none; + } +} diff --git a/client/src/variables.css b/client/src/variables.css index 7082a25..87966ce 100644 --- a/client/src/variables.css +++ b/client/src/variables.css @@ -3,4 +3,3 @@ --color-light: #ebdbb2; --color-yellow: #fabd2f; } - |