@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
121 lines (106 loc) • 3.31 kB
JavaScript
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import NumberInput from '@instructure/quiz-number-input/components/NumberInput/index'
import {ScreenReaderContent} from '@instructure/ui-a11y-content'
import {ItemBodyWrapper} from '@instructure/quiz-rce/components/ItemBodyWrapper/index'
import {withI18nSupport} from '@instructure/quiz-common/with-i18n-support'
import withAsyncDeps from '../../../util/withAsyncDeps'
import {mathjsIsLoaded, loadMathjs, substituteVars} from '../common/util'
import {Decimal} from '@instructure/quiz-i18n/util/Decimal'
import t from '@instructure/quiz-i18n/format-message'
/**
category: Formula
Formula Show component
```jsx_example
<SettingsSwitcher locales={LOCALES}>
<FormulaShow
itemBody="Find `x` + `y`"
scoringData={{
value: {
answerCount: '2',
formula: 'x+y',
generatedSolutions: [{
output: 3333.3333,
inputs: [
{ name: 'x', value: 1111.1111 },
{ name: 'y', value: 2222.2222 }
]
}, {
output: 10000.5,
inputs: [
{ name: 'x', value: 3000.25 },
{ name: 'y', value: 7000.25 }
]
}],
variables: [{
name: 'x',
min: '0',
max: '10000',
precision: '2'
}, {
name: 'y',
min: '0',
max: '10000',
precision: '2'
}]
}
}}
/>
</SettingsSwitcher>
```
**/
@withAsyncDeps(mathjsIsLoaded, loadMathjs)
export default class FormulaShow extends withI18nSupport(Component) {
static propTypes = {
itemBody: PropTypes.string.isRequired,
scoringData: PropTypes.shape({
value: PropTypes.shape({
generatedSolutions: PropTypes.arrayOf(
PropTypes.shape({
inputs: PropTypes.arrayOf(
PropTypes.shape({
name: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
}),
),
output: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
}),
),
}).isRequired,
}).isRequired,
locale: PropTypes.string,
}
static defaultProps = {
locale: null,
}
static contextTypes = {
locale: PropTypes.string,
}
get value() {
if (!this.props.scoringData || this.props.scoringData.value.generatedSolutions.length < 1) {
return ''
}
return this.props.scoringData.value.generatedSolutions[0].output
}
get variables() {
if (!this.props.scoringData || this.props.scoringData.value.generatedSolutions.length < 1) {
return []
}
return this.props.scoringData.value.generatedSolutions[0].inputs
}
render() {
const transformedBody = substituteVars(this.props.itemBody, this.variables, this.locale)
return (
<ItemBodyWrapper itemBody={transformedBody}>
<NumberInput
renderLabel={<ScreenReaderContent>{t('Answer value')}</ScreenReaderContent>}
value={Decimal.toLocaleStringIfValid(this.value, this.locale)}
readOnly
tabIndex={-1}
/>
</ItemBodyWrapper>
)
}
}