UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

185 lines (170 loc) • 5.25 kB
/** @jsx jsx */ import {Component} from 'react' import PropTypes from 'prop-types' import {jsx} from '@instructure/emotion' import {Text} from '@instructure/ui-text' import t from '@instructure/quiz-i18n/format-message' import {ItemBodyWrapper} from '@instructure/quiz-rce/components/ItemBodyWrapper/index' import {RichContentRenderer} from '@instructure/quiz-rce/components/RichContentRenderer/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: Ordering --- Ordering Result component ```jsx_example <SettingsSwitcher locales={LOCALES}> <OrderingResult itemBody="Order these characters from tallest to shortest:" interactionData={{ choices: { uuid4: { id: 'uuid4', itemBody: '<p>Aragorn</p>' }, uuid3: { id: 'uuid3', itemBody: '<p>Gimli</p>' }, uuid2: { id: 'uuid2', itemBody: '<p>Frodo</p>' }, uuid1: { id: 'uuid1', itemBody: '<p>Gollum</p>' } } }} properties={{ displayAnswersParagraph: true, includeLabels: true, topLabel: 'Taller', bottomLabel: 'Shorter' }} scoredData={{ value: [{ userResponded: 'uuid3', resultScore: 0, value: 'uuid4' }, { userResponded: 'uuid4', resultScore: 0, value: 'uuid3' }, { userResponded: 'uuid2', resultScore: 1, value: 'uuid2' }, { userResponded: 'uuid1', resultScore: 1, value: 'uuid1' }] }} /> </SettingsSwitcher> ``` **/ @withStyleOverrides(generateStyle, generateComponentTheme) export default class OrderingResult extends Component { static displayName = 'OrderingResult' static componentId = `Quizzes${this.displayName}` static propTypes = { interactionData: PropTypes.shape({ choices: PropTypes.objectOf( PropTypes.shape({ id: PropTypes.string.isRequired, itemBody: PropTypes.string.isRequired, }), ).isRequired, }).isRequired, itemBody: PropTypes.string.isRequired, properties: PropTypes.shape({ displayAnswersParagraph: PropTypes.bool, includeLabels: PropTypes.bool, topLabel: PropTypes.string, bottomLabel: PropTypes.string, }).isRequired, scoredData: PropTypes.shape({ correct: PropTypes.bool, value: PropTypes.arrayOf( PropTypes.shape({ resultScore: PropTypes.number, userResponded: PropTypes.string, value: PropTypes.string, }), ), }).isRequired, makeStyles: PropTypes.func, styles: PropTypes.object, } componentDidMount() { this.props.makeStyles() } componentDidUpdate() { this.props.makeStyles() } renderLabel(labelPosition) { const {properties} = this.props if (properties.includeLabels) { return ( <div className={labelPosition} css={this.props.styles[labelPosition]}> <Text color="primary">{properties[labelPosition]}</Text> </div> ) } } renderChoices() { const {choices} = this.props.interactionData const {correct, value} = this.props.scoredData if (!value || value.length === 0) { return ( <NoResponse responseHidden={!value} status={typeof correct === 'undefined' ? 'unknown' : 'incorrect'} richContent /> ) } return value.map((answer, idx) => { let status if (answer.resultScore >= 1) { status = 'correct' } else if (answer.resultScore <= 0) { status = 'incorrect' } else { status = 'unknown' } const userChoice = choices[answer.userResponded] const correctAnswer = choices[answer.value] ? choices[answer.value].itemBody : null const key = `choice_${idx}` return ( <div css={this.props.styles.feedbackWrapper} key={key}> {userChoice ? ( <FeedbackWrapper hiddenCorrectAnswerText={t('Correct Order Answer: ')} hiddenIncorrectAnswerText={t('Incorrect Order Answer: ')} correctAnswer={correctAnswer} status={status} richContent > <RichContentRenderer customStyles={this.props.styles.userResponse} content={userChoice.itemBody} /> </FeedbackWrapper> ) : ( <NoResponse correctAnswerLabel={correctAnswer} responseHidden={answer.userResponded === void 0} status={status} richContent /> )} </div> ) }) } render() { return ( <div css={this.props.styles.holder}> <ItemBodyWrapper itemBody={this.props.itemBody}> {this.renderLabel('topLabel')} <div css={this.props.styles.choicesWrapper}>{this.renderChoices()}</div> {this.renderLabel('bottomLabel')} </ItemBodyWrapper> </div> ) } }