You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
51 lines
1.9 KiB
JavaScript
51 lines
1.9 KiB
JavaScript
5 years ago
|
import React, {useState, useRef} from 'react'
|
||
|
import {Button} from './form'
|
||
|
import {DateTime} from 'luxon'
|
||
|
import InfiniteCalendar from 'react-infinite-calendar';
|
||
|
|
||
|
import Modal from '~/components/modal'
|
||
|
|
||
|
import styles from './styles.module.css'
|
||
|
|
||
|
// TODO: At some point make the date input better for accessibility
|
||
|
// (currently just skips tab index)
|
||
|
export default function Input({placeholder: _placeholder, label: _label, error, hint, name, value, onChange, onBlur, isValid}){
|
||
|
const label = (_label === undefined) ? name.replace(name[0], name[0].toUpperCase()) : _label
|
||
|
const displayedValue = value ? DateTime.fromISO(value).toFormat('LLLL dd, yyyy') : _placeholder
|
||
|
const inputRef = useRef()
|
||
|
|
||
|
const [modalShown, setModal] = useState(false)
|
||
|
|
||
|
const handleDateSelect = date => {
|
||
|
onChange({target: {value: DateTime.fromJSDate(date).toISO()}})
|
||
|
handleCancel()
|
||
|
}
|
||
|
const handleCancel = () => {
|
||
|
setModal(false)
|
||
|
setImmediate(()=>inputRef.current?.blur())
|
||
|
}
|
||
|
|
||
|
return (
|
||
|
<div className={styles.formElementContainer}>
|
||
|
{label && <label htmlFor={name}>{label}:</label>}
|
||
|
<div className={styles.complexInput + ((isValid && !error)?'':' ' + styles.invalid)}>
|
||
|
<input readOnly tabIndex={-1} style={{opacity: value ? 1 : .4}} ref={inputRef} onClick={()=>setModal(true)} type="text" name={name} value={displayedValue} onBlur={onBlur} />
|
||
|
</div>
|
||
|
{(hint || error) && <span className={styles.hint}>{error || (isValid ? '' : hint)}</span>}
|
||
|
<Modal title={`Select ${label}`} visible={modalShown} onDeactivate={handleCancel}>
|
||
|
<InfiniteCalendar
|
||
|
width={600}
|
||
|
height={400}
|
||
|
displayOptions={{
|
||
|
layout: 'landscape',
|
||
|
showTodayHelper: false
|
||
|
}}
|
||
|
maxDate={new Date()}
|
||
|
selected={value ? DateTime.fromISO(value).toJSDate() : undefined}
|
||
|
onSelect={handleDateSelect}
|
||
|
/>
|
||
|
</Modal>
|
||
|
</div>
|
||
|
)
|
||
|
}
|