in uui/components/datePickers/RangeDatePickerBody.tsx [100:249]
function RangeDatePickerBodyComp(props: RangeDatePickerBodyProps<RangeDatePickerValue | null>, ref: React.ForwardedRef<HTMLDivElement>): JSX.Element {
const { value: _value, filter } = props;
const {
selectedDate: _selectedDate, inFocus,
} = _value;
const selectedDate = _selectedDate || defaultRangeValue; // also handles null in comparison to default value
const [activeMonth, setActiveMonth] = useState<RangeDatePickerInputType>(inFocus);
const [view, setView] = useState<ViewType>('DAY_SELECTION');
const [month, setMonth] = useState(() => {
return getMonthOnOpen(selectedDate, inFocus);
});
const getRange = (newValue: string | null) => {
if (!filter || filter(uuiDayjs.dayjs(newValue))) {
if (inFocus === 'from') {
return getWithFrom(selectedDate, newValue);
}
if (inFocus === 'to') {
return getWithTo(selectedDate, newValue);
}
}
};
const onBodyValueChange = (v: string | null, part: 'from' | 'to') => {
// selectedDate can be null, other params should always have values
const newRange = v ? getRange(v) : selectedDate;
let newInFocus: RangeDatePickerInputType = null;
const fromChanged = selectedDate.from !== newRange?.from;
const toChanged = selectedDate.to !== newRange?.to;
if (inFocus === 'from' && fromChanged) {
newInFocus = 'to';
} else if (inFocus === 'to' && toChanged) {
newInFocus = 'from';
}
setActiveMonth(part);
props.onValueChange({
selectedDate: newRange ? newRange : selectedDate,
inFocus: newInFocus ?? inFocus,
});
};
const renderDay = (renderProps: DayProps): JSX.Element => {
return (
<Day
{ ...renderProps }
cx={ getDayCX(renderProps.value, selectedDate) }
/>
);
};
const from: StatelessDatePickerBodyValue<string> = {
month,
view: activeMonth === 'from' ? view : 'DAY_SELECTION',
value: null,
};
const to: StatelessDatePickerBodyValue<string> = {
view: activeMonth === 'to' ? view : 'DAY_SELECTION',
month: month.add(1, 'month'),
value: null,
};
const renderPresets = (presets: RangeDatePickerPresets) => {
return (
<React.Fragment>
<div className={ uuiRangeDatePickerBody.separator } />
<CalendarPresets
onPresetSet={ (presetVal) => {
// enable day if smth other were selected
setView('DAY_SELECTION');
setMonth(uuiDayjs.dayjs(presetVal.from));
props.onValueChange({
inFocus: props.value.inFocus,
selectedDate: {
from: uuiDayjs.dayjs(presetVal.from).format(valueFormat),
to: uuiDayjs.dayjs(presetVal.to).format(valueFormat),
},
});
} }
presets={ presets }
/>
</React.Fragment>
);
};
return (
<div
ref={ ref }
className={ cx(css.root, uuiDatePickerBodyBase.container, props.cx) }
{ ...props.rawProps }
>
<FlexRow
cx={ [view === 'DAY_SELECTION' && css.daySelection, css.container] }
alignItems="top"
>
<FlexCell width="auto">
<FlexRow>
<FlexRow
cx={ css.bodesWrapper }
alignItems="top"
>
<StatelessDatePickerBody
key="date-picker-body-left"
cx={ cx(css.fromPicker) }
{ ...from }
onValueChange={ (v) => onBodyValueChange(v, 'from') }
onMonthChange={ (m) => {
setMonth(m);
} }
onViewChange={ (v) => setView(v) }
filter={ props.filter }
isHoliday={ props.isHoliday }
renderDay={ props.renderDay || renderDay }
isDisabled={ view !== 'DAY_SELECTION' && activeMonth === 'to' }
/>
<StatelessDatePickerBody
key="date-picker-body-right"
cx={ cx(css.toPicker) }
{ ...to }
onValueChange={ (v) => onBodyValueChange(v, 'to') }
onMonthChange={ (m) => {
setMonth(m.subtract(1, 'month'));
} }
onViewChange={ (v) => setView(v) }
filter={ props.filter }
renderDay={ props.renderDay || renderDay }
isHoliday={ props.isHoliday }
isDisabled={ view !== 'DAY_SELECTION' && activeMonth === 'from' }
/>
{view !== 'DAY_SELECTION' && (
<div
style={ {
left: activeMonth === 'from' ? '50%' : undefined,
right: activeMonth === 'to' ? '50%' : undefined,
} }
className={ css.blocker }
/>
)}
</FlexRow>
{props.presets && renderPresets(props.presets)}
</FlexRow>
{props.renderFooter && props.renderFooter()}
</FlexCell>
</FlexRow>
</div>
);
}