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.

52 lines
1.9 KiB
JavaScript

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 DateInput({placeholder: _placeholder, label: _label, error, hint, name, value, onChange, onBlur, isValid, minDate, maxDate}){
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)
setTimeout(()=>inputRef.current?.blur(), 0)
}
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
}}
minDate={minDate}
maxDate={maxDate}
selected={value ? DateTime.fromISO(value).toJSDate() : undefined}
onSelect={handleDateSelect}
/>
</Modal>
</div>
)
}