@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
116 lines (103 loc) • 3.4 kB
JavaScript
import React, {useState} from 'react'
import PropTypes from 'prop-types'
import {SimpleSelect} from '@instructure/quiz-common/components/SimpleSelect/index'
import {Flex} from '@instructure/quiz-common/components/Flex/index'
import {Decimal} from '@instructure/quiz-i18n/util/Decimal'
import {ScientificNumberInput} from '@instructure/quiz-number-input/components/ScientificNumberInput'
import t from '@instructure/quiz-i18n/format-message'
import {ABSOLUTE, PERCENT} from './constants'
function MarginOfError({
id,
locale,
margin: marginProp,
marginType,
messages,
numericTypeSelect,
onChange,
value: valueProp,
}) {
const [margin, setMargin] = useState(() => {
if (!marginProp) return ''
try {
return Decimal.toLocaleString(marginProp, locale)
} catch {
return marginProp
}
})
const [value, setValue] = useState(() => {
if (!valueProp) return ''
try {
return Decimal.toLocaleString(valueProp, locale)
} catch {
return valueProp
}
})
const handleMarginChange = (event, newMargin, normalized) => {
setMargin(newMargin)
onChange(event, {id, margin: normalized})
}
const handleMarginTypeChange = (event, {value}) => {
onChange(event, {id, marginType: value})
}
const handleValueChange = (event, newValue, normalized) => {
setValue(newValue)
onChange(event, {id, value: normalized})
}
return (
<Flex alignItems="start">
<Flex.Item shouldGrow shouldShrink margin="0 xx-small">
{numericTypeSelect}
</Flex.Item>
<Flex.Item shouldGrow shouldShrink margin="0 xx-small">
<ScientificNumberInput
renderLabel={t('Answer')}
locale={locale}
messages={messages.value}
onChange={handleValueChange}
value={value}
aria-valuetext={`${value} ${t('Answer')}`}
data-automation="sdk-numeric-marginoferror-response-number-input"
isRequired={true}
/>
</Flex.Item>
<Flex.Item shouldGrow shouldShrink margin="0 xx-small">
<ScientificNumberInput
renderLabel={t('+/- margin')}
locale={locale}
messages={messages.margin}
min={0}
onChange={handleMarginChange}
value={margin}
aria-valuetext={`${margin} ${t('+/- margin')}`}
isRequired={true}
/>
</Flex.Item>
<Flex.Item shouldGrow shouldShrink margin="0 xx-small">
<SimpleSelect renderLabel={t('Type')} onChange={handleMarginTypeChange} value={marginType}>
<SimpleSelect.Option id="margin-of-error-select-option-percent" value={PERCENT}>
{t('Percent')}
</SimpleSelect.Option>
<SimpleSelect.Option id="margin-of-error-select-option-absolute" value={ABSOLUTE}>
{t('Absolute')}
</SimpleSelect.Option>
</SimpleSelect>
</Flex.Item>
</Flex>
)
}
MarginOfError.propTypes = {
id: PropTypes.string.isRequired,
locale: PropTypes.string.isRequired,
margin: PropTypes.string,
marginType: PropTypes.oneOf([PERCENT, ABSOLUTE]).isRequired,
messages: PropTypes.objectOf(PropTypes.array),
numericTypeSelect: PropTypes.node.isRequired,
onChange: PropTypes.func.isRequired,
value: PropTypes.string,
}
MarginOfError.defaultProps = {
margin: void 0,
messages: void 0,
value: void 0,
}
export default MarginOfError