From f281457038b3c892e6adea8064801a7e1294af52 Mon Sep 17 00:00:00 2001 From: chris <kokosias@yahoo.gr> Date: Fri, 23 Jul 2021 18:29:02 +0300 Subject: [PATCH] new funcionality in progress --- .../components/Button.js | 89 +++++++++ .../components/EditorComponent.js | 36 +++- .../components/QuestionComponent.js | 184 ++++++++++++------ .../components/Switch.js | 2 +- .../components/SwitchComponent.js | 1 + editors/demo/src/HHMI/layout/HhmiLayout.js | 1 + 6 files changed, 252 insertions(+), 61 deletions(-) create mode 100644 editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Button.js diff --git a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Button.js b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Button.js new file mode 100644 index 000000000..d11dd3090 --- /dev/null +++ b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Button.js @@ -0,0 +1,89 @@ +import React from 'react'; +import styled, { css } from 'styled-components'; +import PropTypes from 'prop-types'; +import { Button as AntButton } from 'antd'; +import { omit } from 'lodash'; + +import { darken, lighten } from '@pubsweet/ui-toolkit'; + +const colors = { + danger: 'colorError', + error: 'colorError', + success: 'colorSuccess', + // warn: 'colorWarning', +}; + +const StyledButton = styled(AntButton)` + ${props => { + const { status, theme, type } = props; + if (!Object.keys(colors).includes(status)) return null; + const color = theme[colors[status]]; + + // primary + if (type === 'primary') + return css` + background-color: ${color}; + border-color: ${color}; + color: ${theme.colorTextReverse}; + + &:hover, + &:focus, + &:active { + border-color: ${color}; + color: ${theme.colorTextReverse}; + } + + &:hover, + &:focus { + background-color: ${lighten(color, 0.25)}; + } + + &:active { + background-color: ${darken(color, 0.25)}; + } + `; + + // non-primary + return css` + color: ${color}; + border-color: ${color}; + + &:hover, + &:focus { + color: ${lighten(color, 0.25)}; + border-color: ${lighten(color, 0.25)}; + } + + &:active { + color: ${darken(color, 0.25)}; + border-color: ${darken(color, 0.25)}; + } + `; + }} +`; +/** + * API is the same as https://ant.design/components/button/#API, except for the + * `danger` prop, which is ommited in favour of `status`, described below. + */ + +const Button = props => { + const { children, className, ...rest } = props; + const passProps = omit(rest, 'danger'); + + return ( + // eslint-disable-next-line react/jsx-props-no-spreading + <StyledButton className={className} {...passProps}> + {children} + </StyledButton> + ); +}; + +Button.propTypes = { + status: PropTypes.oneOf(['error', 'danger', 'success']), +}; + +Button.defaultProps = { + status: null, +}; + +export default Button; diff --git a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/EditorComponent.js b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/EditorComponent.js index 1359e83cc..e8c4dd509 100644 --- a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/EditorComponent.js +++ b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/EditorComponent.js @@ -9,6 +9,36 @@ import { baseKeymap } from 'prosemirror-commands'; import { undo, redo } from 'prosemirror-history'; import { WaxContext } from 'wax-prosemirror-core'; +const EditorWrapper = styled.div` + border: none; + display: flex; + flex: 2 1 auto; + justify-content: left; + margin-right: 15px; + + .ProseMirror { + white-space: break-spaces; + width: 100%; + word-wrap: break-word; + + &:focus { + outline: none; + } + + p.empty-node:first-child::before { + content: attr(data-content); + } + + .empty-node::before { + color: rgb(170, 170, 170); + float: left; + font-style: italic; + height: 0px; + pointer-events: none; + } + } +`; + const EditorComponent = ({ node, view, getPos }) => { const editorRef = useRef(); @@ -109,7 +139,11 @@ const EditorComponent = ({ node, view, getPos }) => { }; }; - return <div ref={editorRef} />; + return ( + <EditorWrapper> + <div ref={editorRef} /> + </EditorWrapper> + ); }; export default EditorComponent; diff --git a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/QuestionComponent.js b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/QuestionComponent.js index b0904b6dd..651acb0b0 100644 --- a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/QuestionComponent.js +++ b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/QuestionComponent.js @@ -3,60 +3,76 @@ import React, { useContext, useRef, useState } from 'react'; import styled from 'styled-components'; import { TextSelection } from 'prosemirror-state'; import { WaxContext } from 'wax-prosemirror-core'; +import { PlusSquareOutlined, DeleteOutlined } from '@ant-design/icons'; + import EditorComponent from './EditorComponent'; import FeedbackComponent from './FeedbackComponent'; +import SwitchComponent from './SwitchComponent'; +import Button from './Button'; -const QuestionWrapper = styled.div` +const Wrapper = styled.div` display: flex; flex-direction: column; - &:before { - bottom: -20px; - content: 'Answer ' counter(question-item-multiple); - counter-increment: question-item-multiple; - position: relative; - } + width: 100%; `; -const QuestionWrapperInner = styled.div` - border: 1px solid #a5a1a2; - border-radius: 4px; +const InfoRow = styled.div` + color: black; display: flex; - flex-direction: column; - padding: 4px; + flex-direction: row; + padding: 10px 0px 4px 0px; `; -const CorrectLabel = styled.span` - margin-left: auto; +const QuestionNunber = styled.span``; + +const QuestionControlsWrapper = styled.div` + display: flex; + flex-direction: row; `; -const ChooseAnswer = styled.div` +const QuestionWrapper = styled.div` border: 1px solid #a5a1a2; border-radius: 4px; + color: black; display: flex; - flex-direction: row; - height: 25px; - margin-left: auto; - padding: 4px; - >div: first-of-type { - padding-right: 4px; - } + flex: 2 1 auto; + flex-direction: column; + padding: 10px; `; -const YesNoContainer = styled.div` - bottom: 3px; - color: #a5a1a2; - position: relative; +const IconsWrapper = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + + button { + border: none; + } + + span { + cursor: pointer; + } `; -const Question = styled.div` +const QuestionData = styled.div` + align-items: normal; display: flex; flex-direction: row; +`; - .ProseMirror { - background: #ebebf0; - padding: 5px; - width: 90%; - } +const FeedBack = styled.div` + color: black; + margin-top: 10px; +`; + +const FeedBackLabel = styled.span` + font-weight: 700; +`; + +const FeedBackInput = styled.input` + border: none; + display: flex; + width: 100%; `; export default ({ node, view, getPos }) => { @@ -66,11 +82,12 @@ export default ({ node, view, getPos }) => { } = context; const [showExplanation, setShowExplanation] = useState(false); - const [explanationValue, setExplanationValue] = useState(''); - const explanationRef = useRef(null); + const [feadBack, setFeedBack] = useState(''); + + const feedBackRef = useRef(null); const onChangeExplanationInput = () => { - setExplanationValue(explanationRef.current.value); + setFeedBack(feedBackRef.current.value); }; const clickMe = () => { @@ -99,30 +116,79 @@ export default ({ node, view, getPos }) => { const setNoYesValues = () => {}; + const addOption = () => {}; + + const questionNumber = 1; + const questionText = ''; + const readOnly = false; + const feedBackInput = ''; + const showAddIcon = true; + const showRemoveIcon = true; + return ( - <QuestionWrapper> - <CorrectLabel>Correct?</CorrectLabel> - <QuestionWrapperInner> - <Question> - <EditorComponent node={node} view={view} getPos={getPos} /> - <ChooseAnswer> - <YesNoContainer onClick={setNoYesValues}>No</YesNoContainer> - <YesNoContainer onClick={setNoYesValues}>Yes</YesNoContainer> - </ChooseAnswer> - </Question> - <button onClick={clickMe}>Show Explanation</button> - {showExplanation && ( - <input - type="text" - onKeyDown={handleKeyDown} - ref={explanationRef} - onChange={onChangeExplanationInput} - placeholder="type your explanation" - value={explanationValue} - ></input> - )} - <button onClick={removeOption}> X </button> - </QuestionWrapperInner> - </QuestionWrapper> + <Wrapper> + <InfoRow> + <QuestionNunber>Answer {questionNumber}</QuestionNunber> + </InfoRow> + <QuestionControlsWrapper> + <QuestionWrapper> + <QuestionData> + <EditorComponent node={node} view={view} getPos={getPos} /> + + <SwitchComponent /> + </QuestionData> + <FeedBack> + <FeedBackLabel>Feedback</FeedBackLabel> + <FeedBackInput + onChange={feedBackInput} + placeholder="Insert feedback" + ref={feedBackRef} + type="text" + value={feadBack} + /> + </FeedBack> + </QuestionWrapper> + <IconsWrapper> + {showAddIcon && !readOnly && ( + <Button + icon={ + <PlusSquareOutlined onClick={addOption} title="Add Option" /> + } + /> + )} + {showRemoveIcon && !readOnly && ( + <Button + icon={ + <DeleteOutlined onClick={removeOption} title="Delete Option" /> + } + /> + )} + </IconsWrapper> + </QuestionControlsWrapper> + </Wrapper> + + // <QuestionWrapper> + // <CorrectLabel>Correct?</CorrectLabel> + // <QuestionWrapperInner> + // <Question> + // <EditorComponent node={node} view={view} getPos={getPos} /> + // <ChooseAnswer> + // <SwitchComponent /> + // </ChooseAnswer> + // </Question> + // <button onClick={clickMe}>Show Explanation</button> + // {showExplanation && ( + // <input + // type="text" + // onKeyDown={handleKeyDown} + // ref={explanationRef} + // onChange={onChangeExplanationInput} + // placeholder="type your explanation" + // value={explanationValue} + // ></input> + // )} + // <button onClick={removeOption}> X </button> + // </QuestionWrapperInner> + // </QuestionWrapper> ); }; diff --git a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Switch.js b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Switch.js index 294ad2a30..6cad91dad 100644 --- a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Switch.js +++ b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/Switch.js @@ -3,7 +3,7 @@ import PropTypes from 'prop-types'; import styled, { css } from 'styled-components'; import { Switch as AntSwitch } from 'antd'; -import { grid } from '@coko/client'; +import { grid } from '@pubsweet/ui-toolkit'; const Wrapper = styled.span``; diff --git a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/SwitchComponent.js b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/SwitchComponent.js index c3d4c8864..467fd62b0 100644 --- a/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/SwitchComponent.js +++ b/editors/demo/src/HHMI/MultipleChoiceQuestionService/components/SwitchComponent.js @@ -8,6 +8,7 @@ const StyledSwitch = styled(Switch)` span:nth-child(1) { bottom: 36px; + display: flex; left: 4px; position: relative; width: 0px; diff --git a/editors/demo/src/HHMI/layout/HhmiLayout.js b/editors/demo/src/HHMI/layout/HhmiLayout.js index fc036fdda..0ea5183ac 100644 --- a/editors/demo/src/HHMI/layout/HhmiLayout.js +++ b/editors/demo/src/HHMI/layout/HhmiLayout.js @@ -3,6 +3,7 @@ import styled, { ThemeProvider } from 'styled-components'; import { WaxContext, ComponentPlugin } from 'wax-prosemirror-core'; import { grid, th } from '@pubsweet/ui-toolkit'; import { cokoTheme } from '../theme'; +import 'antd/dist/antd.css'; import EditorElements from './EditorElements'; /* Katex css */ -- GitLab