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 a547d2d67..67cf91492 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
@@ -1,6 +1,7 @@
import { FormAddressFieldInput } from '@/object-record/record-field/form-types/components/FormAddressFieldInput';
import { FormBooleanFieldInput } from '@/object-record/record-field/form-types/components/FormBooleanFieldInput';
import { FormFullNameFieldInput } from '@/object-record/record-field/form-types/components/FormFullNameFieldInput';
+import { FormLinksFieldInput } from '@/object-record/record-field/form-types/components/FormLinksFieldInput';
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';
@@ -9,11 +10,13 @@ import { FieldDefinition } from '@/object-record/record-field/types/FieldDefinit
import {
FieldAddressValue,
FieldFullNameValue,
+ FieldLinksValue,
FieldMetadata,
} from '@/object-record/record-field/types/FieldMetadata';
import { isFieldAddress } from '@/object-record/record-field/types/guards/isFieldAddress';
import { isFieldBoolean } from '@/object-record/record-field/types/guards/isFieldBoolean';
import { isFieldFullName } from '@/object-record/record-field/types/guards/isFieldFullName';
+import { isFieldLinks } from '@/object-record/record-field/types/guards/isFieldLinks';
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';
@@ -74,7 +77,14 @@ export const FormFieldInput = ({
) : isFieldAddress(field) ? (
+ ) : isFieldLinks(field) ? (
+
diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx
index 143ee62fb..6feb38319 100644
--- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx
+++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormAddressFieldInput.tsx
@@ -1,7 +1,7 @@
import { FormCountrySelectInput } from '@/object-record/record-field/form-types/components/FormCountrySelectInput';
-import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
-import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer';
import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
+import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer';
+import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
import { FieldAddressDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue';
import { FieldAddressValue } from '@/object-record/record-field/types/FieldMetadata';
@@ -9,7 +9,7 @@ import { InputLabel } from '@/ui/input/components/InputLabel';
type FormAddressFieldInputProps = {
label?: string;
- defaultValue: FieldAddressDraftValue | null;
+ defaultValue?: FieldAddressDraftValue | null;
onPersist: (value: FieldAddressValue) => void;
VariablePicker?: VariablePickerComponent;
readonly?: boolean;
diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormLinksFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormLinksFieldInput.tsx
new file mode 100644
index 000000000..1f8b61702
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormLinksFieldInput.tsx
@@ -0,0 +1,58 @@
+import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer';
+import { FormNestedFieldInputContainer } from '@/object-record/record-field/form-types/components/FormNestedFieldInputContainer';
+import { FormTextFieldInput } from '@/object-record/record-field/form-types/components/FormTextFieldInput';
+import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent';
+import { FieldLinksDraftValue } from '@/object-record/record-field/types/FieldInputDraftValue';
+import { FieldLinksValue } from '@/object-record/record-field/types/FieldMetadata';
+import { InputLabel } from '@/ui/input/components/InputLabel';
+
+type FormLinksFieldInputProps = {
+ label?: string;
+ defaultValue?: FieldLinksValue;
+ onPersist: (value: FieldLinksValue) => void;
+ VariablePicker?: VariablePickerComponent;
+ readonly?: boolean;
+};
+
+export const FormLinksFieldInput = ({
+ label,
+ defaultValue,
+ onPersist,
+ readonly,
+ VariablePicker,
+}: FormLinksFieldInputProps) => {
+ const handleChange =
+ (field: keyof FieldLinksDraftValue) => (updatedLinksPart: string) => {
+ const updatedLinks = {
+ primaryLinkLabel: defaultValue?.primaryLinkLabel ?? '',
+ primaryLinkUrl: defaultValue?.primaryLinkUrl ?? '',
+ [field]: updatedLinksPart,
+ };
+ // We need to validate the links and display an error message if the links are not valid
+ onPersist(updatedLinks);
+ };
+
+ return (
+
+ {label ? {label} : null}
+
+
+
+
+
+ );
+};
diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormLinksFieldInput.stories.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormLinksFieldInput.stories.tsx
new file mode 100644
index 000000000..8dccf506c
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/__stories__/FormLinksFieldInput.stories.tsx
@@ -0,0 +1,31 @@
+import { Meta, StoryObj } from '@storybook/react';
+import { within } from '@storybook/test';
+import { FormLinksFieldInput } from '../FormLinksFieldInput';
+
+const meta: Meta = {
+ title: 'UI/Data/Field/Form/Input/FormLinksFieldInput',
+ component: FormLinksFieldInput,
+ args: {},
+ argTypes: {},
+};
+
+export default meta;
+
+type Story = StoryObj;
+
+export const Default: Story = {
+ args: {
+ label: 'Domain Name',
+ defaultValue: {
+ primaryLinkLabel: 'Google',
+ primaryLinkUrl: 'https://www.google.com',
+ },
+ },
+ play: async ({ canvasElement }) => {
+ const canvas = within(canvasElement);
+
+ await canvas.findByText('Domain Name');
+ await canvas.findByText('Primary Link Label');
+ await canvas.findByText('Google');
+ },
+};