Open vwkd opened 3 weeks ago
I had to make my own with react-imask
and my version just feels kinda wrong, I don't have enough time to make a good date input (couldn't screenshot the blinking cursor):
export const DateTimeInput = (props: DateTimeInputProps) => {
const {
value,
showTimeInput = false,
calendarMinDate = set(new Date(), { year: 1900 }),
calendarMaxDate = new Date(),
onChange,
} = props;
const minDate = set(calendarMinDate, dateResetTime);
const maxDate = set(calendarMaxDate, dateResetTime);
const dateFormat = showTimeInput ? localeDateTimeFormat : localeDateFormat;
const mask = showTimeInput ? localeDateTimeMask : localeDateMask;
return (
<Popover>
<div className="flex w-full items-center gap-2">
<IMaskShadCNInput
mask={mask}
value={value && isValid(value) ? format(value, dateFormat) : ''}
onAccept={(val, mask) => {
if (val === '') {
onChange();
return;
}
if (!mask.masked.isComplete) {
return;
}
if (!isMatch(val, dateFormat)) {
toast.error('Invalid date format', {
description: `Please enter a valid date in the format ${dateFormat}`,
});
onChange();
return;
}
const parsedDate = parse(val, dateFormat, new Date());
onChange(parsedDate);
}}
placeholder={`Pick a date${showTimeInput ? 'time' : ''}`}
/>
<PopoverTrigger asChild>
<Button
className={cn(
'pl-3 text-left font-normal',
!value && 'text-secondary-foreground',
)}
>
<CalendarIcon className="ml-auto h-4 w-4 opacity-50" />
</Button>
</PopoverTrigger>
</div>
<PopoverContent className="w-auto p-0" align="start">
<Calendar
mode="single"
required
fromDate={minDate}
toDate={maxDate}
captionLayout="dropdown"
selected={value}
onSelect={(selectedDate) => {
if (!selectedDate) {
onChange();
return;
}
const date = set(selectedDate, {
hours: value?.getHours() ?? 0,
minutes: value?.getMinutes() ?? 0,
});
onChange(date);
}}
disabled={(date) =>
(minDate && isBefore(date, minDate)) ||
(maxDate && isAfter(date, maxDate)) ||
false
}
initialFocus
/>
{showTimeInput && (
<Input
type="time"
className="mt-2"
// take locale date time string in format that the input expects (24hr time)
value={value && isValid(value) ? format(value, timeFormat) : ''}
// take hours and minutes and update our Date object then change date object to our new value
onChange={(selectedTime) => {
if (!selectedTime.target.value) {
return;
}
const currentTime = parse(
selectedTime.target.value,
timeFormat,
value ?? new Date(),
);
onChange(currentTime);
}}
/>
)}
</PopoverContent>
</Popover>
);
};
import { RefAttributes } from 'react';
import { IMaskInput, IMaskMixin } from 'react-imask';
import { Input } from './ui/input';
export const IMaskShadCNInput = IMaskMixin(({ inputRef, ...props }) => (
<Input {...props} ref={inputRef as RefAttributes<HTMLInputElement>['ref']} />
)) as typeof IMaskInput;
Feature description
It would be great if the Date Picker and Date Range Picker could support keyboard input like the Date Picker and Date Range Picker of Bits UI.
It's often easier to type out a far away date instead of clicking multiple times through the UI.
Affected component/components
Date Picker, Date Range Picker
Additional Context
Similar reported issues that were since closed as stale:
546
2229
4171
Before submitting