Files
twenty/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx
Lucas Bordeau 444e97fa3e Fixed date picker UI that was too overloaded (#5039)
Date picker UI was off because of the recent refactor with new field
types Date and DateTime. We had to allow the date picker to edit both.

In this PR we come back to the previous design and we only use the input
to modify time.

Also we use our Select component instead of the ones from the library
`react-datepicker`

---------

Co-authored-by: Weiko <corentin@twenty.com>
2024-04-23 18:45:32 +02:00

102 lines
2.7 KiB
TypeScript

import { useRef, useState } from 'react';
import styled from '@emotion/styled';
import { Nullable } from 'twenty-ui';
import {
InternalDatePicker,
MONTH_AND_YEAR_DROPDOWN_ID,
MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID,
MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID,
} from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useListenClickOutsideV2 } from '@/ui/utilities/pointer-event/hooks/useListenClickOutsideV2';
const StyledCalendarContainer = styled.div`
background: ${({ theme }) => theme.background.secondary};
border: 1px solid ${({ theme }) => theme.border.color.light};
border-radius: ${({ theme }) => theme.border.radius.md};
box-shadow: ${({ theme }) => theme.boxShadow.strong};
top: 0;
position: absolute;
`;
export type DateInputProps = {
value: Nullable<Date>;
onEnter: (newDate: Nullable<Date>) => void;
onEscape: (newDate: Nullable<Date>) => void;
onClickOutside: (
event: MouseEvent | TouchEvent,
newDate: Nullable<Date>,
) => void;
clearable?: boolean;
onChange?: (newDate: Nullable<Date>) => void;
isDateTimeInput?: boolean;
onClear?: () => void;
};
export const DateInput = ({
value,
onEnter,
onEscape,
onClickOutside,
clearable,
onChange,
isDateTimeInput,
onClear,
}: DateInputProps) => {
const [internalValue, setInternalValue] = useState(value);
const wrapperRef = useRef<HTMLDivElement>(null);
const handleChange = (newDate: Date | null) => {
setInternalValue(newDate);
onChange?.(newDate);
};
const handleClear = () => {
setInternalValue(null);
onClear?.();
};
const { closeDropdown } = useDropdown(MONTH_AND_YEAR_DROPDOWN_ID);
const { closeDropdown: closeDropdownMonthSelect } = useDropdown(
MONTH_AND_YEAR_DROPDOWN_MONTH_SELECT_ID,
);
const { closeDropdown: closeDropdownYearSelect } = useDropdown(
MONTH_AND_YEAR_DROPDOWN_YEAR_SELECT_ID,
);
useListenClickOutsideV2({
refs: [wrapperRef],
listenerId: 'DateInput',
callback: (event) => {
event.stopImmediatePropagation();
closeDropdownYearSelect();
closeDropdownMonthSelect();
closeDropdown();
onClickOutside(event, internalValue);
},
});
return (
<div ref={wrapperRef}>
<StyledCalendarContainer>
<InternalDatePicker
date={internalValue ?? new Date()}
onChange={handleChange}
onMouseSelect={(newDate: Date | null) => {
onEnter(newDate);
}}
clearable={clearable ? clearable : false}
isDateTimeInput={isDateTimeInput}
onEnter={onEnter}
onEscape={onEscape}
onClear={handleClear}
/>
</StyledCalendarContainer>
</div>
);
};