import React, { useContext, useRef, useState, useMemo, useEffect } from 'react'; import styled from 'styled-components'; import { TextSelection } from 'prosemirror-state'; import { WaxContext, DocumentHelpers } from 'wax-prosemirror-core'; const FeedBack = styled.div` color: black; margin-top: 10px; `; const FeedBackLabel = styled.span` font-weight: 700; `; const FeedBackInput = styled.textarea` border: none; display: flex; font-family: Fira Sans Condensed; width: 100%; resize: vertical; white-space: pre-wrap; overflow-wrap: break-word; background-attachment: local; background-image: linear-gradient(to right, white 10px, transparent 10px), linear-gradient(to left, white 10px, transparent 10px), repeating-linear-gradient( white, white 30px, #ccc 30px, #ccc 31px, white 31px ); line-height: 31px; padding: 8px 10px; &:focus { outline: none; } ::placeholder { color: rgb(170, 170, 170); font-style: italic; } `; export default ({ node, getPos, readOnly }) => { const context = useContext(WaxContext); const { pmViews: { main }, } = context; const [isFirstRun, setFirstRun] = useState(true); const [feedBack, setFeedBack] = useState(node.attrs.feedback); const feedBackRef = useRef(null); const feedBackInput = () => { setFeedBack(feedBackRef.current.value); const allNodes = getNodes(main); allNodes.forEach(singleNode => { if (singleNode.node.attrs.id === node.attrs.id) { main.dispatch( main.state.tr.setNodeMarkup(getPos(), undefined, { ...singleNode.node.attrs, feedback: feedBackRef.current.value, }), ); } }); setNullSelection(); setHeight(); return false; }; const setHeight = () => { const textarea = feedBackRef.current; if (!textarea) return; const heightLimit = 200; textarea.style.height = ''; textarea.style.height = `${Math.min(textarea.scrollHeight, heightLimit)}px`; }; const setNullSelection = () => { main.dispatch( main.state.tr.setSelection(TextSelection.create(main.state.tr.doc, null)), ); }; const onFocus = () => { setTimeout(() => { setNullSelection(); }, 50); }; useEffect(() => { setTimeout(() => { setFirstRun(false); }); }, []); return useMemo( () => ( <FeedBack> <FeedBackLabel>Feedback</FeedBackLabel> <FeedBackInput onChange={feedBackInput} onFocus={onFocus} placeholder="Insert feedback" readOnly={readOnly} ref={feedBackRef} rows="1" style={{ height: setHeight() }} type="text" value={feedBack} /> </FeedBack> ), [feedBack, isFirstRun], ); }; const getNodes = view => { const allNodes = DocumentHelpers.findBlockNodes(view.state.doc); const multipleChoiceNodes = []; allNodes.forEach(node => { if ( node.node.type.name === 'multiple_choice' || node.node.type.name === 'multiple_choice_single_correct' || node.node.type.name === 'true_false' || node.node.type.name === 'true_false_single_correct' || node.node.type.name === 'matching_container' || node.node.type.name === 'fill_the_gap_container' || node.node.type.name === 'multiple_drop_down_container' || node.node.type.name === 'numerical_answer_container' ) { multipleChoiceNodes.push(node); } }); return multipleChoiceNodes; };