diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormBooleanFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormBooleanFieldInput.tsx index ae7a78e8a..ff4502bee 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormBooleanFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormBooleanFieldInput.tsx @@ -1,5 +1,5 @@ import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer'; -import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer'; +import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer'; import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer'; import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; @@ -84,7 +84,7 @@ export const FormBooleanFieldInput = ({ {label ? {label} : null} - {draftValue.type === 'static' ? ( @@ -101,7 +101,7 @@ export const FormBooleanFieldInput = ({ onRemove={readonly ? undefined : handleUnlinkVariable} /> )} - + {VariablePicker && !readonly ? ( { - const { - goBackToPreviousHotkeyScope, - setHotkeyScopeAndMemorizePreviousScope, - } = usePreviousHotkeyScope(); - - const onFocus = () => { - setHotkeyScopeAndMemorizePreviousScope( - FormFieldInputHotKeyScope.FormFieldInput, - ); - }; - - const onBlur = () => { - goBackToPreviousHotkeyScope(); - }; - return ( - + {children} ); diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormFieldInputInnerContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormFieldInputInnerContainer.tsx new file mode 100644 index 000000000..32e6e7a88 --- /dev/null +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormFieldInputInnerContainer.tsx @@ -0,0 +1,90 @@ +import { FormFieldInputHotKeyScope } from '@/object-record/record-field/form-types/constants/FormFieldInputHotKeyScope'; +import { usePreviousHotkeyScope } from '@/ui/utilities/hotkey/hooks/usePreviousHotkeyScope'; +import { css } from '@emotion/react'; +import styled from '@emotion/styled'; +import { forwardRef, HTMLAttributes, Ref } from 'react'; + +type FormFieldInputInnerContainerProps = { + hasRightElement: boolean; + multiline?: boolean; + readonly?: boolean; + preventSetHotkeyScope?: boolean; +}; + +const StyledFormFieldInputInnerContainer = styled.div` + background-color: ${({ theme }) => theme.background.transparent.lighter}; + border: 1px solid ${({ theme }) => theme.border.color.medium}; + border-top-left-radius: ${({ theme }) => theme.border.radius.sm}; + border-bottom-left-radius: ${({ theme }) => theme.border.radius.sm}; + + ${({ multiline, hasRightElement, theme }) => + multiline || !hasRightElement + ? css` + border-right: auto; + border-bottom-right-radius: ${theme.border.radius.sm}; + border-top-right-radius: ${theme.border.radius.sm}; + ` + : css` + border-right: none; + border-bottom-right-radius: none; + border-top-right-radius: none; + `} + + box-sizing: border-box; + display: flex; + overflow: ${({ multiline }) => (multiline ? 'auto' : 'hidden')}; + width: 100%; +`; + +export const FormFieldInputInnerContainer = forwardRef( + ( + { + className, + children, + onFocus, + onBlur, + hasRightElement, + multiline, + readonly, + preventSetHotkeyScope = false, + }: HTMLAttributes & FormFieldInputInnerContainerProps, + ref: Ref, + ) => { + const { + goBackToPreviousHotkeyScope, + setHotkeyScopeAndMemorizePreviousScope, + } = usePreviousHotkeyScope(); + + const handleFocus = (e: React.FocusEvent) => { + onFocus?.(e); + + if (!preventSetHotkeyScope) { + setHotkeyScopeAndMemorizePreviousScope( + FormFieldInputHotKeyScope.FormFieldInput, + ); + } + }; + + const handleBlur = (e: React.FocusEvent) => { + onBlur?.(e); + + if (!preventSetHotkeyScope) { + goBackToPreviousHotkeyScope(); + } + }; + + return ( + + {children} + + ); + }, +); diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormFieldInputInputContainer.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormFieldInputInputContainer.tsx deleted file mode 100644 index 36dbe3d86..000000000 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormFieldInputInputContainer.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import { css } from '@emotion/react'; -import styled from '@emotion/styled'; - -const StyledFormFieldInputInputContainer = styled.div<{ - hasRightElement: boolean; - multiline?: boolean; - readonly?: boolean; -}>` - background-color: ${({ theme }) => theme.background.transparent.lighter}; - border: 1px solid ${({ theme }) => theme.border.color.medium}; - border-top-left-radius: ${({ theme }) => theme.border.radius.sm}; - border-bottom-left-radius: ${({ theme }) => theme.border.radius.sm}; - - ${({ multiline, hasRightElement, theme }) => - multiline || !hasRightElement - ? css` - border-right: auto; - border-bottom-right-radius: ${theme.border.radius.sm}; - border-top-right-radius: ${theme.border.radius.sm}; - ` - : css` - border-right: none; - border-bottom-right-radius: none; - border-top-right-radius: none; - `} - - box-sizing: border-box; - display: flex; - overflow: ${({ multiline }) => (multiline ? 'auto' : 'hidden')}; - width: 100%; -`; - -export const FormFieldInputInputContainer = StyledFormFieldInputInputContainer; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormMultiSelectFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormMultiSelectFieldInput.tsx index 97d47e514..7574e4ae6 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormMultiSelectFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormMultiSelectFieldInput.tsx @@ -1,7 +1,7 @@ import styled from '@emotion/styled'; import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer'; -import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer'; +import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer'; import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer'; import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone'; import { FormMultiSelectFieldInputHotKeyScope } from '@/object-record/record-field/form-types/constants/FormMultiSelectFieldInputHotKeyScope'; @@ -17,9 +17,9 @@ import { isStandaloneVariableString } from '@/workflow/utils/isStandaloneVariabl import { useTheme } from '@emotion/react'; import { useId, useState } from 'react'; import { isDefined } from 'twenty-shared/utils'; +import { VisibilityHidden } from 'twenty-ui/accessibility'; import { IconChevronDown } from 'twenty-ui/display'; import { SelectOption } from 'twenty-ui/input'; -import { VisibilityHidden } from 'twenty-ui/accessibility'; type FormMultiSelectFieldInputProps = { label?: string; @@ -185,7 +185,7 @@ export const FormMultiSelectFieldInput = ({ {label ? {label} : null} - {draftValue.type === 'static' ? ( @@ -231,7 +231,7 @@ export const FormMultiSelectFieldInput = ({ onRemove={readonly ? undefined : handleUnlinkVariable} /> )} - + {draftValue.type === 'static' && draftValue.editingMode === 'edit' && ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx index c03e35d2a..9c69d77e7 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormNumberFieldInput.tsx @@ -1,5 +1,5 @@ import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer'; -import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer'; +import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer'; import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer'; import { VariableChipStandalone } from '@/object-record/record-field/form-types/components/VariableChipStandalone'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; @@ -108,7 +108,7 @@ export const FormNumberFieldInput = ({ {label ? {label} : null} - @@ -128,7 +128,7 @@ export const FormNumberFieldInput = ({ onRemove={readonly ? undefined : handleUnlinkVariable} /> )} - + {VariablePicker && !readonly ? ( {label} : null} - - + {VariablePicker && !readonly && ( ) : ( - - + )} {isDefined(VariablePicker) && !readonly && ( diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx index f112dc7d2..20a4f27bb 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormSingleRecordPicker.tsx @@ -1,6 +1,6 @@ import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord'; import { FormFieldInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputContainer'; -import { FormFieldInputInputContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInputContainer'; +import { FormFieldInputInnerContainer } from '@/object-record/record-field/form-types/components/FormFieldInputInnerContainer'; import { FormFieldInputRowContainer } from '@/object-record/record-field/form-types/components/FormFieldInputRowContainer'; import { FormSingleRecordFieldChip } from '@/object-record/record-field/form-types/components/FormSingleRecordFieldChip'; import { VariablePickerComponent } from '@/object-record/record-field/form-types/types/VariablePickerComponent'; @@ -20,7 +20,7 @@ import { isDefined, isValidUuid } from 'twenty-shared/utils'; import { IconChevronDown, IconForbid } from 'twenty-ui/display'; import { LightIconButton } from 'twenty-ui/input'; -const StyledFormSelectContainer = styled(FormFieldInputInputContainer)` +const StyledFormSelectContainer = styled(FormFieldInputInnerContainer)` justify-content: space-between; align-items: center; padding-right: ${({ theme }) => theme.spacing(1)}; @@ -132,6 +132,7 @@ export const FormSingleRecordPicker = ({ {label} : null} - - + {VariablePicker && !readonly ? ( {label} : null} - {draftValue.type === 'static' ? ( @@ -113,7 +113,7 @@ export const FormUuidFieldInput = ({ onRemove={readonly ? undefined : handleUnlinkVariable} /> )} - + {VariablePicker && !readonly ? ( setHoveredField(null)} > - { handleFieldClick(field.id); @@ -220,7 +220,7 @@ export const WorkflowEditActionFormBuilder = ({ /> )} - + {!actionOptions.readonly && (isFieldSelected(field.id) || isFieldHovered(field.id)) && ( @@ -263,7 +263,7 @@ export const WorkflowEditActionFormBuilder = ({ - { const { label, name } = getDefaultFormFieldSettings( @@ -296,7 +296,7 @@ export const WorkflowEditActionFormBuilder = ({ {t`Add Field`} - + diff --git a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx index a0ccf87f3..957abebb3 100644 --- a/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx +++ b/packages/twenty-front/src/modules/workflow/workflow-variables/components/WorkflowVariablesDropdown.tsx @@ -1,6 +1,8 @@ import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown'; import { StyledDropdownButtonContainer } from '@/ui/layout/dropdown/components/StyledDropdownButtonContainer'; -import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown'; +import { useDropdownV2 } from '@/ui/layout/dropdown/hooks/useDropdownV2'; +import { isDropdownOpenComponentState } from '@/ui/layout/dropdown/states/isDropdownOpenComponentState'; +import { extractComponentState } from '@/ui/utilities/state/component-state/utils/extractComponentState'; import { WorkflowVariablesDropdownFieldItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownFieldItems'; import { WorkflowVariablesDropdownObjectItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownObjectItems'; import { WorkflowVariablesDropdownWorkflowStepItems } from '@/workflow/workflow-variables/components/WorkflowVariablesDropdownWorkflowStepItems'; @@ -11,6 +13,7 @@ import { StepOutputSchema } from '@/workflow/workflow-variables/types/StepOutput import { useTheme } from '@emotion/react'; import styled from '@emotion/styled'; import { useState } from 'react'; +import { useRecoilValue } from 'recoil'; import { isDefined } from 'twenty-shared/utils'; import { IconVariablePlus } from 'twenty-ui/display'; @@ -43,7 +46,10 @@ export const WorkflowVariablesDropdown = ({ const theme = useTheme(); const dropdownId = `${SEARCH_VARIABLES_DROPDOWN_ID}-${inputId}`; - const { isDropdownOpen, closeDropdown } = useDropdown(dropdownId); + const isDropdownOpen = useRecoilValue( + extractComponentState(isDropdownOpenComponentState, dropdownId), + ); + const { closeDropdown } = useDropdownV2(); const availableVariablesInWorkflowStep = useAvailableVariablesInWorkflowStep({ objectNameSingularToSelect, }); @@ -68,7 +74,7 @@ export const WorkflowVariablesDropdown = ({ const handleSubItemSelect = (subItem: string) => { onVariableSelect(subItem); setSelectedStep(initialStep); - closeDropdown(); + closeDropdown(dropdownId); }; const handleBack = () => {