UNPKG

@instructure/quiz-interactions

Version:

A React UI component Library for quiz interaction types.

143 lines (126 loc) 4.54 kB
/** @jsx jsx */ import {Component} from 'react' import PropTypes from 'prop-types' import {jsx} from '@instructure/emotion' import RemoveChoiceButton from '../../../common/edit/components/RemoveChoiceButton' import {toErrors} from '../../../../util/instUIMessages' import t from '@instructure/quiz-i18n/format-message' import {View} from '@instructure/ui-view' import {Text} from '@instructure/ui-text' import {ScreenReaderContent} from '@instructure/ui-a11y-content' import {TextInput} from '@instructure/quiz-common/components/TextInput/index' import {Flex} from '@instructure/quiz-common/components/Flex/index' export default class MatchEdit extends Component { static displayName = 'MatchEdit' static componentId = `Quizzes${this.displayName}` static propTypes = { answerBody: PropTypes.string.isRequired, answerErrors: PropTypes.array.isRequired, disabled: PropTypes.bool, editAnswer: PropTypes.func.isRequired, editQuestion: PropTypes.func.isRequired, hasOnlyOneMatch: PropTypes.bool.isRequired, index: PropTypes.number.isRequired, questionBody: PropTypes.string.isRequired, questionErrors: PropTypes.array.isRequired, questionId: PropTypes.string.isRequired, removeMatch: PropTypes.func.isRequired, } static defaultProps = { disabled: false, } // ============= // HANDLERS // ============= handleAnswerChange = event => { this.props.editAnswer(this.props.questionId, event.target.value) } handleAnswerBlur = event => { this.props.editAnswer(this.props.questionId, event.target.value.trim()) } handleQuestionChange = event => { this.props.editQuestion(this.props.questionId, event.target.value) } handleQuestionBlur = event => { this.props.editQuestion(this.props.questionId, event.target.value.trim()) } handleRemoveMatch = () => { this.props.removeMatch(this.props.questionId) } // ============= // RENDERS // ============= renderLabel = (label, screenReaderContent) => { return ( <View> <ScreenReaderContent>{screenReaderContent}</ScreenReaderContent> <Text aria-hidden="true">{label}</Text> </View> ) } render() { const {hasOnlyOneMatch, questionBody, answerBody} = this.props return ( <Flex direction="row" data-role="questionWrapper" width={'100%'} justifyItems="space-between" alignItems="start" > <Flex.Item shouldGrow> <TextInput renderLabel={this.renderLabel( t('Question'), t('Prompt {n, number} question', {n: this.props.index + 1}), )} isRequired={true} defaultValue={questionBody} messages={toErrors(this.props.questionErrors)} onChange={this.handleQuestionChange} onBlur={this.handleQuestionBlur} data-automation="sdk-matching-question" /> </Flex.Item> <Flex.Item as="div" shouldGrow> <hr css={{marginTop: '48px'}} /> </Flex.Item> <Flex.Item shouldGrow> <Flex direction="row" width="100%" alignItems="start" gap="small"> <Flex.Item shouldGrow> <TextInput renderLabel={this.renderLabel( t('Answer'), t('Prompt {n, number} answer', { n: this.props.index + 1, }), )} isRequired={true} defaultValue={answerBody} messages={toErrors(this.props.answerErrors)} onChange={this.handleAnswerChange} onBlur={this.handleAnswerBlur} data-automation="sdk-matching-answer" /> </Flex.Item> {!hasOnlyOneMatch && !this.props.disabled && ( <Flex.Item> <View as="div" margin="xx-large 0 0 0" themeOverride={{marginXxLarge: '30px'}}> <RemoveChoiceButton screenReaderText={t('Remove Question/Answer pair: {question} - {answer}', { question: questionBody, answer: answerBody, })} onRemoveChoice={this.handleRemoveMatch} choiceId={this.props.questionId} data-automation="sdk-matching-delete" /> </View> </Flex.Item> )} </Flex> </Flex.Item> </Flex> ) } }