From 17b7e703b404944466d9170425905ac960723513 Mon Sep 17 00:00:00 2001 From: Thomas Trompette Date: Mon, 7 Apr 2025 18:56:59 +0200 Subject: [PATCH] Refacto form select input (#11426) - small fixes on form design - refacto form select input to use the existing select component --- .../components/FormFieldInput.tsx | 2 - .../components/FormCountryCodeSelectInput.tsx | 6 +- .../components/FormCountrySelectInput.tsx | 7 +- .../components/FormCurrencyFieldInput.tsx | 17 +- .../components/FormSelectFieldInput.tsx | 214 ++---------------- .../FormPhoneFieldInput.stories.tsx | 71 ------ .../modules/ui/input/components/Select.tsx | 8 +- .../ui/input/components/SelectControl.tsx | 23 +- .../components/WorkflowStepBody.tsx | 2 +- .../WorkflowEditActionFormBuilder.tsx | 12 +- .../WorkflowEditActionFormFieldSettings.tsx | 6 +- .../WorkflowFormFieldSettingsRecordPicker.tsx | 2 +- ...lowEditActionFormFieldSettings.stories.tsx | 6 +- .../utils/getDefaultFormFieldSettings.ts | 2 +- 14 files changed, 80 insertions(+), 298 deletions(-) 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 244a35ab4..bfde9d454 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 @@ -92,9 +92,7 @@ export const FormFieldInput = ({ onChange={onChange} VariablePicker={VariablePicker} options={field.metadata.options} - clearLabel={field.label} readonly={readonly} - placeholder={placeholder} /> ) : isFieldFullName(field) ? ( ({ label: `${countryName} (+${callingCode})`, value: countryCode, - color: 'transparent', - icon: (props: IconComponentProps) => + Icon: (props: IconComponentProps) => Flag({ width: props.size, height: props.size }), }), ); @@ -36,7 +35,7 @@ export const FormCountryCodeSelectInput = ({ { label: 'No country', value: '', - icon: IconCircleOff, + Icon: IconCircleOff, }, ...countryList, ]; @@ -62,7 +61,6 @@ export const FormCountryCodeSelectInput = ({ defaultValue={selectedCountryCode} readonly={readonly} VariablePicker={VariablePicker} - preventDisplayPadding /> ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCountrySelectInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCountrySelectInput.tsx index 6f1bc59ba..7f0adb959 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCountrySelectInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCountrySelectInput.tsx @@ -24,8 +24,7 @@ export const FormCountrySelectInput = ({ ({ countryName, Flag }) => ({ label: countryName, value: countryName, - color: 'transparent', - icon: (props: IconComponentProps) => + Icon: (props: IconComponentProps) => Flag({ width: props.size, height: props.size }), }), ); @@ -33,7 +32,7 @@ export const FormCountrySelectInput = ({ { label: 'No country', value: '', - icon: IconCircleOff, + Icon: IconCircleOff, }, ...countryList, ]; @@ -59,8 +58,6 @@ export const FormCountrySelectInput = ({ defaultValue={selectedCountryName} readonly={readonly} VariablePicker={VariablePicker} - placeholder="Select a country" - preventDisplayPadding /> ); }; diff --git a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx index f3c3acbf4..ae56f1caf 100644 --- a/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx +++ b/packages/twenty-front/src/modules/object-record/record-field/form-types/components/FormCurrencyFieldInput.tsx @@ -8,6 +8,7 @@ import { FormFieldCurrencyValue } from '@/object-record/record-field/types/Field import { SETTINGS_FIELD_CURRENCY_CODES } from '@/settings/data-model/constants/SettingsFieldCurrencyCodes'; import { InputLabel } from '@/ui/input/components/InputLabel'; import { useMemo } from 'react'; +import { IconCircleOff } from 'twenty-ui/display'; type FormCurrencyFieldInputProps = { label?: string; @@ -25,13 +26,22 @@ export const FormCurrencyFieldInput = ({ readonly, }: FormCurrencyFieldInputProps) => { const currencies = useMemo(() => { - return Object.entries(SETTINGS_FIELD_CURRENCY_CODES).map( + const currencies = Object.entries(SETTINGS_FIELD_CURRENCY_CODES).map( ([key, { Icon, label }]) => ({ value: key, - icon: Icon, + Icon, label: `${label} (${key})`, }), ); + + return [ + { + label: 'No currency', + value: '', + Icon: IconCircleOff, + }, + ...currencies, + ]; }, []); const handleAmountMicrosChange = ( @@ -59,11 +69,8 @@ export const FormCurrencyFieldInput = ({ defaultValue={defaultValue?.currencyCode ?? ''} onChange={handleCurrencyCodeChange} options={currencies} - clearLabel={'Currency Code'} VariablePicker={VariablePicker} readonly={readonly} - placeholder="Select a currency" - preventDisplayPadding /> void; VariablePicker?: VariablePickerComponent; options: SelectOption[]; - clearLabel?: string; readonly?: boolean; - preventDisplayPadding?: boolean; - placeholder?: string; }; -const StyledDisplayModeReadonlyContainer = styled.div` - align-items: center; - background: transparent; - border: none; - display: flex; - font-family: inherit; - padding-inline: ${({ theme }) => theme.spacing(2)}; - width: 100%; -`; - -const StyledDisplayModeContainer = styled(StyledDisplayModeReadonlyContainer)` - cursor: pointer; - - &:hover, - &[data-open='true'] { - background-color: ${({ theme }) => theme.background.transparent.lighter}; - } -`; - -const StyledPlaceholder = styled.div` - color: ${({ theme }) => theme.font.color.light}; - font-weight: ${({ theme }) => theme.font.weight.medium}; - width: 100%; -`; - -const StyledSelectInputContainer = styled.div` - position: absolute; - z-index: 1; - top: ${({ theme }) => theme.spacing(8)}; -`; - -const StyledSelectDisplayContainer = styled.div` - display: flex; - width: 100%; -`; - export const FormSelectFieldInput = ({ label, defaultValue, onChange, VariablePicker, options, - clearLabel, readonly, - preventDisplayPadding, - placeholder, }: FormSelectFieldInputProps) => { const inputId = useId(); const hotkeyScope = InlineCellHotkeyScope.InlineCell; - const theme = useTheme(); - const { - setHotkeyScopeAndMemorizePreviousScope, - goBackToPreviousHotkeyScope, - } = usePreviousHotkeyScope(); + const { goBackToPreviousHotkeyScope } = usePreviousHotkeyScope(); const [draftValue, setDraftValue] = useState< | { @@ -114,7 +60,7 @@ export const FormSelectFieldInput = ({ }, ); - const onSubmit = (option: string) => { + const onSelect = (option: string) => { setDraftValue({ type: 'static', value: option, @@ -139,38 +85,10 @@ export const FormSelectFieldInput = ({ goBackToPreviousHotkeyScope(); }; - const [filteredOptions, setFilteredOptions] = useState([]); - - const { resetSelectedItem } = useSelectableList( - SELECT_FIELD_INPUT_SELECTABLE_LIST_COMPONENT_INSTANCE_ID, - ); - - const clearField = () => { - setDraftValue({ - type: 'static', - editingMode: 'view', - value: '', - }); - - onChange(null); - }; - const selectedOption = options.find( (option) => option.value === draftValue.value, ); - const handleClearField = () => { - clearField(); - - goBackToPreviousHotkeyScope(); - }; - - const handleSubmit = (option: SelectOption) => { - onSubmit(option.value); - - resetSelectedItem(); - }; - const handleUnlinkVariable = () => { setDraftValue({ type: 'static', @@ -190,131 +108,43 @@ export const FormSelectFieldInput = ({ onChange(variableName); }; - const handleDisplayModeClick = () => { - if (draftValue.type !== 'static') { - throw new Error( - 'This function can only be called when editing a static value.', - ); - } - - setDraftValue({ - ...draftValue, - editingMode: 'edit', - }); - - setHotkeyScopeAndMemorizePreviousScope(hotkeyScope); - }; - - const handleSelectEnter = (itemId: string) => { - const option = filteredOptions.find((option) => option.value === itemId); - if (isDefined(option)) { - onSubmit(option.value); - resetSelectedItem(); - } - }; - useScopedHotkeys( Key.Escape, () => { onCancel(); - resetSelectedItem(); }, hotkeyScope, - [onCancel, resetSelectedItem], + [onCancel], ); - const optionIds = [ - `No ${label}`, - ...filteredOptions.map((option) => option.value), - ]; - - const placeholderText = placeholder ?? label; - return ( {label ? {label} : null} - - {draftValue.type === 'static' ? ( - readonly ? ( - - {isDefined(selectedOption) ? ( - - - - ) : ( - - )} - - - ) : ( - - Edit - - {isDefined(selectedOption) ? ( - - - - ) : ( - {placeholderText} - )} - - - ) - ) : ( + {draftValue.type === 'static' ? ( +