Files
cunningham/packages/react/src/components/Forms/DatePicker/DateField.tsx
Lebaud Antoine d16ada2825 ♻️(react) make datefield inputs reusable
Refactor the date field input to ensure the inclusion of two identical
and reusable date field inputs in the future DateRangePicker component.
By factoring out the common logic and structure, we can create a more efficient
and easily reusable component for selecting date ranges.
2023-07-10 22:05:33 +02:00

86 lines
2.2 KiB
TypeScript

import React, { useRef } from "react";
import {
AriaDatePickerProps,
useDateField,
useDateSegment,
} from "@react-aria/datepicker";
import { useLocale } from "@react-aria/i18n";
import {
DateFieldState,
useDateFieldState,
DateSegment,
} from "@react-stately/datepicker";
import { createCalendar, DateValue } from "@internationalized/date";
import classNames from "classnames";
import { LabelledBox, Props } from ":/components/Forms/LabelledBox";
interface DateSegmentProps {
currentSegment: DateSegment;
previousSegment: DateSegment;
state: DateFieldState;
}
const DateSegmentInput = ({
currentSegment,
previousSegment,
state,
}: DateSegmentProps) => {
const ref = useRef<HTMLDivElement>(null);
const { segmentProps } = useDateSegment(currentSegment, state, ref);
return (
<div
ref={ref}
{...segmentProps}
className={classNames("c__date-picker__inner__value__segment", {
"c__date-picker__inner__value__segment--empty":
currentSegment.isPlaceholder ||
(currentSegment.type === "literal" && previousSegment?.isPlaceholder),
})}
>
{currentSegment.text}
</div>
);
};
const DateField = (props: AriaDatePickerProps<DateValue>) => {
const { locale } = useLocale();
const state = useDateFieldState({
...props,
locale,
createCalendar,
});
const ref = useRef<HTMLDivElement>(null);
const { fieldProps } = useDateField(props, state, ref);
return (
<div className="c__date-picker__inner__value" {...fieldProps} ref={ref}>
{state.segments.map((segment, i, segments) => (
<DateSegmentInput
key={i}
currentSegment={segment}
previousSegment={segments[i - 1]}
state={state}
/>
))}
</div>
);
};
interface DateFieldBoxProps
extends Props,
Omit<AriaDatePickerProps<DateValue>, "label"> {}
const DateFieldBox = ({ ...props }: DateFieldBoxProps) => (
<LabelledBox {...props}>
<div
className={classNames("c__date-picker__inner", {
"c__date-picker__inner--collapsed": props.labelAsPlaceholder,
})}
>
<DateField {...props} />
</div>
</LabelledBox>
);
export default DateFieldBox;