Untitled
unknown
typescript
4 years ago
5.5 kB
4
Indexable
import React, { useRef, useState } from "react"; import { useLocation } from "react-router-dom"; import { WriteTextControls } from "../../../reducers/interfaceData/types"; import { connect, ConnectedProps } from "react-redux"; import { useEffectOnce, useKeyPressEvent } from "react-use"; // @ts-ignore import { composedWithMarkupTraps } from "../../../hocs/withMarkupTraps/withMarkupTraps"; // @ts-ignore import { Button } from "../../Button"; import { WithMarkUpTrapsProps } from "../../../hocs/withMarkupTraps/types"; import useMobileDetect from "../../../customHooks/useMobileDetect"; import "./index.pcss"; type RootState = { interfaceData: { ui: { writeTextControls: WriteTextControls; }; }; }; const mapState = ({ interfaceData: { ui: { writeTextControls }, }, }: RootState) => ({ writeTextControls, }); const connector = connect(mapState); type PropsFromRedux = ConnectedProps<typeof connector>; type HotKeys = string[]; type Props = PropsFromRedux & { hotKeys: HotKeys; renderMarkupTrapButton: ({ onClick, disabled }: WithMarkUpTrapsProps) => void; onConfirm: (text: string, markAsTrap?: boolean) => void; buttonText: string; placeholder: string; }; const SUBMIT_KEY = "Enter"; const WriteTextControls = ({ writeTextControls, hotKeys, onConfirm, buttonText, placeholder, renderMarkupTrapButton }: Props) => { const textAreaRef = useRef<HTMLTextAreaElement>(null); const [text, setText] = useState(""); const { isMobile } = useMobileDetect(); const { state } = useLocation<{ id: string }>(); const [withLowerCase, setWithLowerCase] = useState(false); useKeyPressEvent(SUBMIT_KEY, () => onEnter()); useEffectOnce(() => checkForLoweCase()); const onEnter = () => { if (!isUserWroteText()) { return; } onConfirm(getText()); handleResetText(); setFocusOnTextArea(); }; const checkForLoweCase = () => { if (!writeTextControls.options || !writeTextControls.options.withLowerCase || !writeTextControls.options.withLowerCase.length) { return; } const { id } = state; return setWithLowerCase(Boolean(writeTextControls.options.withLowerCase.find((gameId) => gameId === id))); }; const renderHotKeys = (hotKeys: string[]) => { if (!hotKeys || !hotKeys.length) { return null; } const getTextWithHotKey = (cursorPosition: number, hotKey: string) => { return [text.slice(0, cursorPosition).concat(hotKey), text.slice(cursorPosition)].join(""); }; const onClick = (e: React.MouseEvent<HTMLButtonElement>, hotKey: string) => { e.preventDefault(); const cursorPosition = textAreaRef?.current?.selectionStart; if (cursorPosition) { const text = getTextWithHotKey(cursorPosition, hotKey); setText(text); } }; return hotKeys.map((hotKey) => ( <Button key={hotKey} classNames="write-text-controls__hotKey" clickHandler={(e: React.MouseEvent<HTMLButtonElement>) => onClick(e, hotKey)} text={hotKey} /> )); }; const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => { setText(e.target.value); }; const handleResetText = () => { setText(""); }; const setFocusOnTextArea = () => { textAreaRef?.current?.focus(); }; const getText = () => { if (withLowerCase) { return text.toLowerCase(); } return text; }; const isUserWroteText = () => { return text.trim().length; }; const setInitialSettings = () => { handleResetText(); setFocusOnTextArea(); }; const onClick = (e: React.MouseEvent<HTMLButtonElement>, markAsTrap?: boolean) => { e.preventDefault(); onConfirm(getText(), markAsTrap); setInitialSettings(); }; const onAltClick = (e: React.MouseEvent<HTMLButtonElement>) => { e.preventDefault(); onConfirm(""); setInitialSettings(); }; return ( <div className="write-text-controls"> <form className="write-text-controls__form"> {renderHotKeys(hotKeys || writeTextControls.quotes)} <textarea ref={textAreaRef} onChange={handleChange} className="write-text-controls__textarea" cols={10} rows={2.5} placeholder={placeholder || writeTextControls.placeholder} value={text} autoFocus={!isMobile} /> <Button classNames="write-text-controls__button write-text-controls__button--with-margin-bottom" clickHandler={onClick} disabled={!isUserWroteText()} text={writeTextControls.ready} /> <Button classNames="write-text-controls__button" clickHandler={onAltClick} text={buttonText || writeTextControls.noText} /> </form> {renderMarkupTrapButton({ onClick: (e: React.MouseEvent<HTMLButtonElement>) => onClick(e, true), disabled: false, })} </div> ); }; export default connector(composedWithMarkupTraps(WriteTextControls));
Editor is loading...