diff --git a/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx
index 8a11b321550e..38084a4d26ae 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-field/components/FormFieldInput.tsx
@@ -3,6 +3,7 @@ import { FormBooleanFieldInput } from '@/object-record/record-field/form-types/c
import { FormEmailsFieldInput } from '@/object-record/record-field/form-types/components/FormEmailsFieldInput';
import { FormFullNameFieldInput } from '@/object-record/record-field/form-types/components/FormFullNameFieldInput';
import { FormLinksFieldInput } from '@/object-record/record-field/form-types/components/FormLinksFieldInput';
+import { FormDateFieldInput } from '@/object-record/record-field/form-types/components/FormDateFieldInput';
import { FormNumberFieldInput } from '@/object-record/record-field/form-types/components/FormNumberFieldInput';
import { FormSelectFieldInput } from '@/object-record/record-field/form-types/components/FormSelectFieldInput';
import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
@@ -20,6 +21,7 @@ import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFiel
import { isFieldEmails } from '@/object-record/record-field/types/guards/isFieldEmails';
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks';
+import { isFieldDate } from '@/object-record/record-field/types/guards/isFieldDate';
import { isFieldNumber } from '@/object-record/record-field/types/guards/isFieldNumber';
import { isFieldSelect } from '@/object-record/record-field/types/guards/isFieldSelect';
import { isFieldText } from '@/object-record/record-field/types/guards/isFieldText';
@@ -98,5 +100,12 @@ export const FormFieldInput = ({
onPersist={onPersist}
VariablePicker={VariablePicker}
/>
+ ) : isFieldDate(field) ? (
+
) : null;
};
diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateFieldInput.tsx
new file mode 100644
index 000000000000..751741c6d85d
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormDateFieldInput.tsx
@@ -0,0 +1,374 @@
+import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
+import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer';
+import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer';
+import { VariableChip } from '@/object-record/record-field/form-types/components/VariableChip';
+import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
+import { StyledCalendarContainer } from '@/ui/field/input/components/DateInput';
+import { InputLabel } from '@/ui/input/components/InputLabel';
+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 { MAX_DATE } from '@/ui/input/components/internal/date/constants/MaxDate';
+import { MIN_DATE } from '@/ui/input/components/internal/date/constants/MinDate';
+import { parseDateToString } from '@/ui/input/components/internal/date/utils/parseDateToString';
+import { parseStringToDate } from '@/ui/input/components/internal/date/utils/parseStringToDate';
+import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
+import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
+import { UserContext } from '@/users/contexts/UserContext';
+import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariableString';
+import { css } from '@emotion/react';
+import styled from '@emotion/styled';
+import {
+ ChangeEvent,
+ KeyboardEvent,
+ useContext,
+ useId,
+ useRef,
+ useState,
+} from 'react';
+import { isDefined, Nullable, TEXT_INPUT_STYLE } from 'twenty-ui';
+
+const StyledInputContainer = styled(FormFieldInputInputContainer)`
+ display: grid;
+ grid-template-columns: 1fr;
+ grid-template-rows: 1fr 0px;
+ overflow: visible;
+ position: relative;
+`;
+
+const StyledDateInputAbsoluteContainer = styled.div`
+ position: absolute;
+`;
+
+const StyledDateInput = styled.input<{ hasError?: boolean }>`
+ ${TEXT_INPUT_STYLE}
+
+ ${({ hasError, theme }) =>
+ hasError &&
+ css`
+ color: ${theme.color.red};
+ `};
+`;
+
+const StyledDateInputContainer = styled.div`
+ position: relative;
+ z-index: 1;
+`;
+
+type DraftValue =
+ | {
+ type: 'static';
+ value: string | null;
+ mode: 'view' | 'edit';
+ }
+ | {
+ type: 'variable';
+ value: string;
+ };
+
+type FormDateFieldInputProps = {
+ label?: string;
+ defaultValue: string | undefined;
+ onPersist: (value: string | null) => void;
+ VariablePicker?: VariablePickerComponent;
+};
+
+export const FormDateFieldInput = ({
+ label,
+ defaultValue,
+ onPersist,
+ VariablePicker,
+}: FormDateFieldInputProps) => {
+ const { timeZone } = useContext(UserContext);
+
+ const inputId = useId();
+
+ const [draftValue, setDraftValue] = useState(
+ isStandaloneVariableString(defaultValue)
+ ? {
+ type: 'variable',
+ value: defaultValue,
+ }
+ : {
+ type: 'static',
+ value: defaultValue ?? null,
+ mode: 'view',
+ },
+ );
+
+ const draftValueAsDate = isDefined(draftValue.value)
+ ? new Date(draftValue.value)
+ : null;
+
+ const [pickerDate, setPickerDate] =
+ useState>(draftValueAsDate);
+
+ const datePickerWrapperRef = useRef(null);
+
+ const [inputDateTime, setInputDateTime] = useState(
+ isDefined(draftValueAsDate) && !isStandaloneVariableString(defaultValue)
+ ? parseDateToString({
+ date: draftValueAsDate,
+ isDateTimeInput: false,
+ userTimezone: timeZone,
+ })
+ : '',
+ );
+
+ const persistDate = (newDate: Nullable) => {
+ if (!isDefined(newDate)) {
+ onPersist(null);
+ } else {
+ const newDateISO = newDate.toISOString();
+
+ onPersist(newDateISO);
+ }
+ };
+
+ 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,
+ );
+
+ const displayDatePicker =
+ draftValue.type === 'static' && draftValue.mode === 'edit';
+
+ useListenClickOutside({
+ refs: [datePickerWrapperRef],
+ listenerId: 'FormDateFieldInput',
+ callback: (event) => {
+ event.stopImmediatePropagation();
+
+ closeDropdownYearSelect();
+ closeDropdownMonthSelect();
+ closeDropdown();
+ handlePickerClickOutside();
+ },
+ enabled: displayDatePicker,
+ });
+
+ const handlePickerChange = (newDate: Nullable) => {
+ setDraftValue({
+ type: 'static',
+ mode: 'edit',
+ value: newDate?.toDateString() ?? null,
+ });
+
+ setInputDateTime(
+ isDefined(newDate)
+ ? parseDateToString({
+ date: newDate,
+ isDateTimeInput: false,
+ userTimezone: timeZone,
+ })
+ : '',
+ );
+
+ setPickerDate(newDate);
+
+ persistDate(newDate);
+ };
+
+ const handlePickerEnter = () => {};
+
+ const handlePickerEscape = () => {
+ // FIXME: Escape key is not handled properly by the underlying DateInput component. We need to solve that.
+
+ setDraftValue({
+ type: 'static',
+ value: draftValue.value,
+ mode: 'view',
+ });
+ };
+
+ const handlePickerClickOutside = () => {
+ setDraftValue({
+ type: 'static',
+ value: draftValue.value,
+ mode: 'view',
+ });
+ };
+
+ const handlePickerClear = () => {
+ setDraftValue({
+ type: 'static',
+ value: null,
+ mode: 'view',
+ });
+
+ setPickerDate(null);
+
+ setInputDateTime('');
+
+ persistDate(null);
+ };
+
+ const handlePickerMouseSelect = (newDate: Nullable) => {
+ setDraftValue({
+ type: 'static',
+ value: newDate?.toDateString() ?? null,
+ mode: 'view',
+ });
+
+ setPickerDate(newDate);
+
+ setInputDateTime(
+ isDefined(newDate)
+ ? parseDateToString({
+ date: newDate,
+ isDateTimeInput: false,
+ userTimezone: timeZone,
+ })
+ : '',
+ );
+
+ persistDate(newDate);
+ };
+
+ const handleInputFocus = () => {
+ setDraftValue({
+ type: 'static',
+ mode: 'edit',
+ value: draftValue.value,
+ });
+ };
+
+ const handleInputChange = (event: ChangeEvent) => {
+ setInputDateTime(event.target.value);
+ };
+
+ const handleInputKeydown = (event: KeyboardEvent) => {
+ if (event.key !== 'Enter') {
+ return;
+ }
+
+ const inputDateTimeTrimmed = inputDateTime.trim();
+
+ if (inputDateTimeTrimmed === '') {
+ handlePickerClear();
+
+ return;
+ }
+
+ const parsedInputDateTime = parseStringToDate({
+ dateAsString: inputDateTimeTrimmed,
+ isDateTimeInput: false,
+ userTimezone: timeZone,
+ });
+
+ if (!isDefined(parsedInputDateTime)) {
+ return;
+ }
+
+ let validatedDate = parsedInputDateTime;
+ if (parsedInputDateTime < MIN_DATE) {
+ validatedDate = MIN_DATE;
+ } else if (parsedInputDateTime > MAX_DATE) {
+ validatedDate = MAX_DATE;
+ }
+
+ setDraftValue({
+ type: 'static',
+ value: validatedDate.toDateString(),
+ mode: 'edit',
+ });
+
+ setPickerDate(validatedDate);
+
+ setInputDateTime(
+ parseDateToString({
+ date: validatedDate,
+ isDateTimeInput: false,
+ userTimezone: timeZone,
+ }),
+ );
+
+ persistDate(validatedDate);
+ };
+
+ const handleVariableTagInsert = (variableName: string) => {
+ setDraftValue({
+ type: 'variable',
+ value: variableName,
+ });
+
+ setInputDateTime('');
+
+ onPersist(variableName);
+ };
+
+ const handleUnlinkVariable = () => {
+ setDraftValue({
+ type: 'static',
+ value: null,
+ mode: 'view',
+ });
+
+ setPickerDate(null);
+
+ onPersist(null);
+ };
+
+ return (
+
+ {label ? {label} : null}
+
+
+
+ {draftValue.type === 'static' ? (
+ <>
+
+
+ {draftValue.mode === 'edit' ? (
+
+
+
+
+
+
+
+ ) : null}
+ >
+ ) : (
+
+ )}
+
+
+ {VariablePicker ? (
+
+ ) : null}
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormDateFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormDateFieldInput.stories.tsx
new file mode 100644
index 000000000000..39a313fb809c
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormDateFieldInput.stories.tsx
@@ -0,0 +1,370 @@
+import { MAX_DATE } from '@/ui/input/components/internal/date/constants/MaxDate';
+import { MIN_DATE } from '@/ui/input/components/internal/date/constants/MinDate';
+import { parseDateToString } from '@/ui/input/components/internal/date/utils/parseDateToString';
+import { expect } from '@storybook/jest';
+import { Meta, StoryObj } from '@storybook/react';
+import {
+ fn,
+ userEvent,
+ waitFor,
+ waitForElementToBeRemoved,
+ within,
+} from '@storybook/test';
+import { DateTime } from 'luxon';
+import { FormDateFieldInput } from '../FormDateFieldInput';
+
+const meta: Meta = {
+ title: 'UI/Data/Field/Form/Input/FormDateFieldInput',
+ component: FormDateFieldInput,
+ args: {},
+ argTypes: {},
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: '2024-12-09T13:20:19.631Z',
+ },
+ play: async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+
+ await canvas.findByText('Created At');
+ await canvas.findByDisplayValue('12/09/2024');
+ },
+};
+
+export const WithDefaultEmptyValue: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: undefined,
+ },
+ play: async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+
+ await canvas.findByText('Created At');
+ await canvas.findByDisplayValue('');
+ await canvas.findByPlaceholderText('mm/dd/yyyy');
+ },
+};
+
+export const SetsDateWithInput: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: undefined,
+ onPersist: fn(),
+ },
+ play: async ({ canvasElement, args }) => {
+ const canvas = within(canvasElement);
+
+ const input = await canvas.findByPlaceholderText('mm/dd/yyyy');
+
+ await userEvent.click(input);
+
+ const dialog = await canvas.findByRole('dialog');
+ expect(dialog).toBeVisible();
+
+ await userEvent.type(input, '12/08/2024{enter}');
+
+ await waitFor(() => {
+ expect(args.onPersist).toHaveBeenCalledWith('2024-12-08T00:00:00.000Z');
+ });
+
+ expect(dialog).toBeVisible();
+ },
+};
+
+export const SetsDateWithDatePicker: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: undefined,
+ onPersist: fn(),
+ },
+ play: async ({ canvasElement, args }) => {
+ const canvas = within(canvasElement);
+
+ const input = await canvas.findByPlaceholderText('mm/dd/yyyy');
+ expect(input).toBeVisible();
+
+ await userEvent.click(input);
+
+ const datePicker = await canvas.findByRole('dialog');
+ expect(datePicker).toBeVisible();
+
+ const dayToChoose = await within(datePicker).findByRole('option', {
+ name: 'Choose Saturday, December 7th, 2024',
+ });
+
+ await Promise.all([
+ userEvent.click(dayToChoose),
+
+ waitForElementToBeRemoved(datePicker),
+ waitFor(() => {
+ expect(args.onPersist).toHaveBeenCalledWith(
+ expect.stringMatching(/^2024-12-07/),
+ );
+ }),
+ waitFor(() => {
+ expect(canvas.getByDisplayValue('12/07/2024')).toBeVisible();
+ }),
+ ]);
+ },
+};
+
+export const ResetsDateByClickingButton: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: '2024-12-09T13:20:19.631Z',
+ onPersist: fn(),
+ },
+ play: async ({ canvasElement, args }) => {
+ const canvas = within(canvasElement);
+
+ const input = await canvas.findByPlaceholderText('mm/dd/yyyy');
+ expect(input).toBeVisible();
+
+ await userEvent.click(input);
+
+ const datePicker = await canvas.findByRole('dialog');
+ expect(datePicker).toBeVisible();
+
+ const clearButton = await canvas.findByText('Clear');
+
+ await Promise.all([
+ userEvent.click(clearButton),
+
+ waitForElementToBeRemoved(datePicker),
+ waitFor(() => {
+ expect(args.onPersist).toHaveBeenCalledWith(null);
+ }),
+ waitFor(() => {
+ expect(input).toHaveDisplayValue('');
+ }),
+ ]);
+ },
+};
+
+export const ResetsDateByErasingInputContent: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: '2024-12-09T13:20:19.631Z',
+ onPersist: fn(),
+ },
+ play: async ({ canvasElement, args }) => {
+ const canvas = within(canvasElement);
+
+ const input = await canvas.findByPlaceholderText('mm/dd/yyyy');
+ expect(input).toBeVisible();
+
+ expect(input).toHaveDisplayValue('12/09/2024');
+
+ await userEvent.clear(input);
+
+ await Promise.all([
+ userEvent.type(input, '{Enter}'),
+
+ waitForElementToBeRemoved(() => canvas.queryByRole('dialog')),
+ waitFor(() => {
+ expect(args.onPersist).toHaveBeenCalledWith(null);
+ }),
+ waitFor(() => {
+ expect(input).toHaveDisplayValue('');
+ }),
+ ]);
+ },
+};
+
+export const DefaultsToMinValueWhenTypingReallyOldDate: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: undefined,
+ onPersist: fn(),
+ },
+ play: async ({ canvasElement, args }) => {
+ const canvas = within(canvasElement);
+
+ const input = await canvas.findByPlaceholderText('mm/dd/yyyy');
+ expect(input).toBeVisible();
+
+ await userEvent.click(input);
+
+ const datePicker = await canvas.findByRole('dialog');
+ expect(datePicker).toBeVisible();
+
+ await Promise.all([
+ userEvent.type(input, '02/02/1500{Enter}'),
+
+ waitFor(() => {
+ expect(args.onPersist).toHaveBeenCalledWith(MIN_DATE.toISOString());
+ }),
+ waitFor(() => {
+ expect(input).toHaveDisplayValue(
+ parseDateToString({
+ date: MIN_DATE,
+ isDateTimeInput: false,
+ userTimezone: undefined,
+ }),
+ );
+ }),
+ waitFor(() => {
+ const expectedDate = DateTime.fromJSDate(MIN_DATE)
+ .toLocal()
+ .set({
+ day: MIN_DATE.getUTCDate(),
+ month: MIN_DATE.getUTCMonth() + 1,
+ year: MIN_DATE.getUTCFullYear(),
+ hour: 0,
+ minute: 0,
+ second: 0,
+ millisecond: 0,
+ });
+
+ const selectedDay = within(datePicker).getByRole('option', {
+ selected: true,
+ name: (accessibleName) => {
+ // The name looks like "Choose Sunday, December 31st, 1899"
+ return accessibleName.includes(expectedDate.toFormat('yyyy'));
+ },
+ });
+ expect(selectedDay).toBeVisible();
+ }),
+ ]);
+ },
+};
+
+export const DefaultsToMaxValueWhenTypingReallyFarDate: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: undefined,
+ onPersist: fn(),
+ },
+ play: async ({ canvasElement, args }) => {
+ const canvas = within(canvasElement);
+
+ const input = await canvas.findByPlaceholderText('mm/dd/yyyy');
+ expect(input).toBeVisible();
+
+ await userEvent.click(input);
+
+ const datePicker = await canvas.findByRole('dialog');
+ expect(datePicker).toBeVisible();
+
+ await Promise.all([
+ userEvent.type(input, '02/02/2500{Enter}'),
+
+ waitFor(() => {
+ expect(args.onPersist).toHaveBeenCalledWith(MAX_DATE.toISOString());
+ }),
+ waitFor(() => {
+ expect(input).toHaveDisplayValue(
+ parseDateToString({
+ date: MAX_DATE,
+ isDateTimeInput: false,
+ userTimezone: undefined,
+ }),
+ );
+ }),
+ waitFor(() => {
+ const expectedDate = DateTime.fromJSDate(MAX_DATE)
+ .toLocal()
+ .set({
+ day: MAX_DATE.getUTCDate(),
+ month: MAX_DATE.getUTCMonth() + 1,
+ year: MAX_DATE.getUTCFullYear(),
+ hour: 0,
+ minute: 0,
+ second: 0,
+ millisecond: 0,
+ });
+
+ const selectedDay = within(datePicker).getByRole('option', {
+ selected: true,
+ name: (accessibleName) => {
+ // The name looks like "Choose Thursday, December 30th, 2100"
+ return accessibleName.includes(expectedDate.toFormat('yyyy'));
+ },
+ });
+ expect(selectedDay).toBeVisible();
+ }),
+ ]);
+ },
+};
+
+export const SwitchesToStandaloneVariable: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: undefined,
+ onPersist: fn(),
+ VariablePicker: ({ onVariableSelect }) => {
+ return (
+
+ );
+ },
+ },
+ play: async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+
+ const addVariableButton = await canvas.findByText('Add variable');
+ await userEvent.click(addVariableButton);
+
+ const variableTag = await canvas.findByText('test');
+ expect(variableTag).toBeVisible();
+
+ const removeVariableButton = canvas.getByTestId(/^remove-icon/);
+
+ await Promise.all([
+ userEvent.click(removeVariableButton),
+
+ waitForElementToBeRemoved(variableTag),
+ waitFor(() => {
+ const input = canvas.getByPlaceholderText('mm/dd/yyyy');
+ expect(input).toBeVisible();
+ }),
+ ]);
+ },
+};
+
+export const ClickingOutsideDoesNotResetInputState: Story = {
+ args: {
+ label: 'Created At',
+ defaultValue: '2024-12-09T13:20:19.631Z',
+ onPersist: fn(),
+ },
+ play: async ({ canvasElement, args }) => {
+ const defaultValueAsDisplayString = parseDateToString({
+ date: new Date(args.defaultValue!),
+ isDateTimeInput: false,
+ userTimezone: undefined,
+ });
+
+ const canvas = within(canvasElement);
+
+ const input = await canvas.findByPlaceholderText('mm/dd/yyyy');
+ expect(input).toBeVisible();
+ expect(input).toHaveDisplayValue(defaultValueAsDisplayString);
+
+ await userEvent.type(input, '{Backspace}{Backspace}');
+
+ const datePicker = await canvas.findByRole('dialog');
+ expect(datePicker).toBeVisible();
+
+ await Promise.all([
+ userEvent.click(canvasElement),
+
+ waitForElementToBeRemoved(datePicker),
+ ]);
+
+ expect(args.onPersist).not.toHaveBeenCalled();
+
+ expect(input).toHaveDisplayValue(defaultValueAsDisplayString.slice(0, -2));
+ },
+};
diff --git a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/DateFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/DateFieldInput.tsx
index 0e67f4baa436..74ad1528189e 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/DateFieldInput.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-field/meta-types/input/components/DateFieldInput.tsx
@@ -4,8 +4,8 @@ import { useDateField } from '@/object-record/record-field/meta-types/hooks/useD
import { DateInput } from '@/ui/field/input/components/DateInput';
import { isDefined } from '~/utils/isDefined';
-import { usePersistField } from '../../../hooks/usePersistField';
import { FieldInputClickOutsideEvent } from '@/object-record/record-field/meta-types/input/components/DateTimeFieldInput';
+import { usePersistField } from '../../../hooks/usePersistField';
type FieldInputEvent = (persist: () => void) => void;
diff --git a/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx b/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx
index 858436a9744e..5d587ee303b5 100644
--- a/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx
+++ b/packages/twenty-front/src/modules/ui/field/input/components/DateInput.tsx
@@ -1,5 +1,4 @@
import styled from '@emotion/styled';
-import { useRef, useState } from 'react';
import { Nullable } from 'twenty-ui';
import {
@@ -10,8 +9,9 @@ import {
} from '@/ui/input/components/internal/date/components/InternalDatePicker';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
+import { useRef, useState } from 'react';
-const StyledCalendarContainer = styled.div`
+export const StyledCalendarContainer = styled.div`
background: ${({ theme }) => theme.background.transparent.secondary};
backdrop-filter: ${({ theme }) => theme.blur.medium};
border: 1px solid ${({ theme }) => theme.border.color.light};
@@ -32,6 +32,7 @@ export type DateInputProps = {
isDateTimeInput?: boolean;
onClear?: () => void;
onSubmit?: (newDate: Nullable) => void;
+ hideHeaderInput?: boolean;
};
export const DateInput = ({
@@ -44,6 +45,7 @@ export const DateInput = ({
isDateTimeInput,
onClear,
onSubmit,
+ hideHeaderInput,
}: DateInputProps) => {
const [internalValue, setInternalValue] = useState(value);
@@ -97,6 +99,7 @@ export const DateInput = ({
onEnter={onEnter}
onEscape={onEscape}
onClear={handleClear}
+ hideHeaderInput={hideHeaderInput}
/>
diff --git a/packages/twenty-front/src/modules/ui/input/components/internal/date/components/AbsoluteDatePickerHeader.tsx b/packages/twenty-front/src/modules/ui/input/components/internal/date/components/AbsoluteDatePickerHeader.tsx
index 6ffeb3fc3da6..1c0e9fcc3484 100644
--- a/packages/twenty-front/src/modules/ui/input/components/internal/date/components/AbsoluteDatePickerHeader.tsx
+++ b/packages/twenty-front/src/modules/ui/input/components/internal/date/components/AbsoluteDatePickerHeader.tsx
@@ -38,6 +38,7 @@ type AbsoluteDatePickerHeaderProps = {
nextMonthButtonDisabled: boolean;
isDateTimeInput?: boolean;
timeZone: string;
+ hideInput?: boolean;
};
export const AbsoluteDatePickerHeader = ({
@@ -51,6 +52,7 @@ export const AbsoluteDatePickerHeader = ({
nextMonthButtonDisabled,
isDateTimeInput,
timeZone,
+ hideInput = false,
}: AbsoluteDatePickerHeaderProps) => {
const endOfDayDateTimeInLocalTimezone = DateTime.now().set({
day: date.getDate(),
@@ -66,12 +68,15 @@ export const AbsoluteDatePickerHeader = ({
return (
<>
-
+ {!hideInput && (
+
+ )}
+