@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
116 lines (101 loc) • 2.98 kB
JavaScript
import React, {Component} from 'react'
import PropTypes from 'prop-types'
import {ItemBodyWrapper} from '@instructure/quiz-rce/components/ItemBodyWrapper/index'
import {ScreenReaderContent} from '@instructure/ui-a11y-content'
import {Decimal} from '@instructure/quiz-i18n/util/Decimal'
import {TextInput} from '@instructure/quiz-common/components/TextInput/index'
import {parseSeparators} from '@instructure/quiz-common/util/parseSeparators'
import {ApplyLocaleContext} from '@instructure/ui-i18n'
import t from '@instructure/quiz-i18n/format-message'
/**
---
category: Numeric
---
Numeric Show component
```jsx_example
<SettingsSwitcher locales={LOCALES}>
<NumericShow
itemBody="x is an integer and 9 < x^2 < 99. What's the max value of x, minus the minimum value of x"
scoringData={{
value: [{
type: 'exactResponse',
id: '1',
value: '18'
}, {
type: 'withinARange',
id: '2',
start: '18',
end: '18'
}, {
type: 'preciseResponse',
id: '3',
value: '18',
precision: '1',
precisionType: 'decimals'
}, {
type: 'marginOfError',
id: '4',
value: '18',
margin: '0.4',
marginType: 'absolute'
}]
}}
/>
</SettingsSwitcher>
```
**/
export default class NumericShow extends Component {
static propTypes = {
itemBody: PropTypes.string.isRequired,
locale: PropTypes.string,
scoringData: PropTypes.shape({
value: PropTypes.array,
}),
separatorConfig: PropTypes.shape({
decimalSeparator: PropTypes.string,
thousandSeparator: PropTypes.string,
}),
}
static contextType = ApplyLocaleContext
static defaultProps = {
locale: void 0,
scoringData: void 0,
}
componentDidMount() {
Decimal.accountSettingDelimiters = this.props.separatorConfig
? parseSeparators(this.props.separatorConfig)
: null
}
get locale() {
return this.props.locale || this.context.locale || 'en-US'
}
get firstCriteria() {
const {scoringData} = this.props
return (scoringData && scoringData.value && scoringData.value[0]) || {}
}
get value() {
const {type, value, start, end} = this.firstCriteria
if (type === 'withinARange') {
return t('{minimum} to {maximum} inclusive', {
minimum: this.formatNumber(start),
maximum: this.formatNumber(end),
})
}
return this.formatNumber(value)
}
formatNumber(value) {
return isNaN(value) ? value : Decimal.toLocaleString(value.toString(), this.locale)
}
render() {
return (
<ItemBodyWrapper itemBody={this.props.itemBody}>
<TextInput
renderLabel={<ScreenReaderContent>{t('Answer value')}</ScreenReaderContent>}
interaction="readonly"
tabIndex={-1}
defaultValue={this.value}
/>
</ItemBodyWrapper>
)
}
}