UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

156 lines (143 loc) 4.66 kB
/** @jsx jsx */ import {Component} from 'react' import PropTypes from 'prop-types' import find from 'lodash/fp/find' import {Text} from '@instructure/ui-text' import {jsx} from '@instructure/emotion' import t from '@instructure/quiz-i18n/format-message' import {ItemBodyWrapper} from '@instructure/quiz-rce/components/ItemBodyWrapper/index' import {FeedbackWrapper, NoResponse} from '@instructure/quiz-results-feedback' import generateStyle from './styles' import generateComponentTheme from './theme' import {withStyleOverrides} from '@instructure/quiz-common/util/withStyleOverrides' /** --- category: Matching --- Matching Result component ```jsx_example <SettingsSwitcher locales={LOCALES}> <MatchingResult itemBody="Match the name of the celestial body on the left with its correct classification." interactionData={{ questions: [ { id: 'quuid1', itemBody: 'Mars' }, { id: 'quuid2', itemBody: 'Phobos' }, { id: 'quuid3', itemBody: 'Andromeda' }, { id: 'quuid4', itemBody: 'Alpha Centauri' } ], answers: [ 'Planet', 'Moon', 'Nebula', 'Star', 'Galaxy - this is a very long answer - this is a very long answer - this is a very long answer' ] }} scoredData={{ value: [{ id: 'quuid1', userResponded: 'Planet', value: 'Planet' }, { id: 'quuid2', userResponded: 'Moon', value: 'Moon' }, { id: 'quuid3', userResponded: 'Nebula', value: 'Nebula' }, { id: 'quuid4', userResponded: 'Star', value: 'GalaxyGalaxy - this is a very long answer - this is a very long answer - this is a very long answer' }] }} /> </SettingsSwitcher> ``` **/ @withStyleOverrides(generateStyle, generateComponentTheme) class MatchingResult extends Component { static displayName = 'MatchingResult' static componentId = `Quizzes${this.displayName}` static propTypes = { interactionData: PropTypes.shape({ questions: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string, itemBody: PropTypes.string, }), ), }).isRequired, itemBody: PropTypes.string.isRequired, scoredData: PropTypes.shape({ correct: PropTypes.bool, value: PropTypes.arrayOf( PropTypes.shape({ id: PropTypes.string.isRequired, resultScore: PropTypes.number, userResponded: PropTypes.string, value: PropTypes.string, }), ), }).isRequired, styles: PropTypes.object, } getAnswerBodyForQuestion(questionId) { const answer = find({id: String(questionId)}, this.props.scoredData.value || {}) return answer && answer.value } renderAnswer(response, answerBody) { const correctnessKnown = typeof this.props.scoredData.correct !== 'undefined' let status = 'incorrect' if (response && response.resultScore) { status = 'correct' } else if ((!response || !response.resultScore) && correctnessKnown) { status = 'incorrect' } else { status = 'unknown' } return ( <div css={this.props.styles.answer}> {response && response.userResponded ? ( <FeedbackWrapper userResponse={response.userResponded} correctAnswer={answerBody} status={status} hiddenCorrectAnswerText={t('Correct match: ')} hiddenIncorrectAnswerText={t('Incorrect match: ')} /> ) : ( <NoResponse correctAnswerLabel={answerBody} responseHidden={!this.props.scoredData.value} status={status} /> )} </div> ) } render() { return ( <ItemBodyWrapper itemBody={this.props.itemBody}> <div> {this.props.interactionData.questions.map(question => { const response = find({id: String(question.id)}, this.props.scoredData.value || {}) const answerBody = this.getAnswerBodyForQuestion(question.id) return ( <div css={this.props.styles.item} key={question.id}> <div css={this.props.styles.question} data-testid="question"> <Text color="primary">{question.itemBody}</Text> </div> <div css={this.props.styles.divider} /> {this.renderAnswer(response, answerBody)} </div> ) })} </div> </ItemBodyWrapper> ) } } export default MatchingResult