@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
143 lines (126 loc) • 4.54 kB
JavaScript
/** @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>
)
}
}