@instructure/quiz-interactions
Version:
A React UI component Library for quiz interaction types.
97 lines (82 loc) • 2.44 kB
JavaScript
import React, {useState, useRef, useEffect, useCallback} from 'react'
import PropTypes from 'prop-types'
import {Checkbox} from '@instructure/ui-checkbox'
import Alert from '../Alert'
import t from '@instructure/quiz-i18n/format-message'
const noop = () => {}
const dummyImg = 'https://i.ytimg.com/vi/LgkAebhJ7iE/maxresdefault.jpg'
function clone(children, props) {
const filteredProps = {}
for (const key in props) {
if (props[key] !== void 0) {
filteredProps[key] = props[key]
}
}
return React.cloneElement(children, filteredProps)
}
function EditStateProvider({children}) {
const [itemState, setItemState] = useState({})
const [errorsAreShowing, setErrorsAreShowing] = useState(true)
const alertRef = useRef(null)
const uploadRequestsRef = useRef({})
useEffect(() => {
return () => {
Object.values(uploadRequestsRef.current).forEach(clearTimeout)
}
}, [])
const handleUpload = useCallback((id, callback) => {
delete uploadRequestsRef.current[id]
callback(dummyImg)
}, [])
const handleErrorsAreShowingChange = e => {
setErrorsAreShowing(e.target.checked)
}
const notifyScreenreader = useCallback(content => {
alertRef.current?.setAlert(content)
}, [])
const changeItemState = useCallback(stateMod => {
setItemState(state => ({...state, ...stateMod}))
}, [])
const cancelMediaUpload = useCallback(id => {
clearTimeout(uploadRequestsRef.current[id])
delete uploadRequestsRef.current[id]
}, [])
const mediaUpload = useCallback(
(file, callback) => {
if (uploadRequestsRef.current[file] !== void 0) {
cancelMediaUpload(file)
}
uploadRequestsRef.current[file] = setTimeout(
() => handleUpload(file, callback),
2000 + Math.random() * 2000,
)
},
[cancelMediaUpload, handleUpload],
)
return (
<div>
<Alert ref={alertRef} />
{clone(children, {
...itemState,
changeItemState,
notifyScreenreader,
cancelMediaUpload,
errorsAreShowing,
openImportModal: noop,
mediaUpload,
})}
<div>
<br />
<Checkbox
onChange={handleErrorsAreShowingChange}
checked={errorsAreShowing}
label={t('Show validation errors')}
/>
</div>
</div>
)
}
EditStateProvider.propTypes = {
children: PropTypes.node.isRequired,
}
export default EditStateProvider