mirror of
https://github.com/lingble/twenty.git
synced 2025-10-30 12:22:29 +00:00
fix: Improve Usability of Adding Options via Return Key for Multi-Select Field (#7450)
Fixes #6602 This is the approach that I followed based on these comments https://github.com/twentyhq/twenty/issues/6602#issuecomment-2356870311, https://github.com/twentyhq/twenty/issues/6602#issuecomment-2330737907 - Create forward ref in `<TextInput>` component - Create ref to select text in parent component `<SettingsDataModelFieldSelectFormOptionRow>` and pass it to `<TextInput>` --------- Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { DropResult } from '@hello-pangea/dnd';
|
||||
import { useState } from 'react';
|
||||
import { Controller, useFormContext } from 'react-hook-form';
|
||||
import { IconPlus } from 'twenty-ui';
|
||||
import { z } from 'zod';
|
||||
@@ -79,7 +78,6 @@ const StyledButton = styled(LightButton)`
|
||||
export const SettingsDataModelFieldSelectForm = ({
|
||||
fieldMetadataItem,
|
||||
}: SettingsDataModelFieldSelectFormProps) => {
|
||||
const [focusedOptionId, setFocusedOptionId] = useState('');
|
||||
const { initialDefaultValue, initialOptions } =
|
||||
useSelectSettingsFormInitialValues({ fieldMetadataItem });
|
||||
|
||||
@@ -190,10 +188,6 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
const newOptions = getOptionsWithNewOption();
|
||||
|
||||
setFormValue('options', newOptions);
|
||||
|
||||
const lastOptionId = newOptions[newOptions.length - 1].id;
|
||||
|
||||
setFocusedOptionId(lastOptionId);
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -227,7 +221,7 @@ export const SettingsDataModelFieldSelectForm = ({
|
||||
<SettingsDataModelFieldSelectFormOptionRow
|
||||
key={option.id}
|
||||
option={option}
|
||||
focused={focusedOptionId === option.id}
|
||||
isNewRow={index === options.length - 1}
|
||||
onChange={(nextOption) => {
|
||||
const nextOptions = toSpliced(
|
||||
options,
|
||||
|
||||
@@ -33,7 +33,7 @@ type SettingsDataModelFieldSelectFormOptionRowProps = {
|
||||
onRemoveAsDefault?: () => void;
|
||||
onInputEnter?: () => void;
|
||||
option: FieldMetadataItemOption;
|
||||
focused?: boolean;
|
||||
isNewRow?: boolean;
|
||||
};
|
||||
|
||||
const StyledRow = styled.div`
|
||||
@@ -67,7 +67,7 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({
|
||||
onRemoveAsDefault,
|
||||
onInputEnter,
|
||||
option,
|
||||
focused,
|
||||
isNewRow,
|
||||
}: SettingsDataModelFieldSelectFormOptionRowProps) => {
|
||||
const theme = useTheme();
|
||||
|
||||
@@ -129,10 +129,11 @@ export const SettingsDataModelFieldSelectFormOptionRow = ({
|
||||
value: getOptionValueFromLabel(label),
|
||||
})
|
||||
}
|
||||
focused={focused}
|
||||
RightIcon={isDefault ? IconCheck : undefined}
|
||||
maxLength={OPTION_VALUE_MAXIMUM_LENGTH}
|
||||
onInputEnter={handleInputEnter}
|
||||
autoFocusOnMount={isNewRow}
|
||||
autoSelectOnMount={isNewRow}
|
||||
/>
|
||||
<Dropdown
|
||||
dropdownId={dropdownIds.actions}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import { H2Title } from 'twenty-ui';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { TextArea } from '@/ui/input/components/TextArea';
|
||||
import styled from '@emotion/styled';
|
||||
import { ServerlessFunctionNewFormValues } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
||||
import { TextArea } from '@/ui/input/components/TextArea';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import styled from '@emotion/styled';
|
||||
import { H2Title } from 'twenty-ui';
|
||||
|
||||
const StyledInputsContainer = styled.div`
|
||||
display: flex;
|
||||
@@ -25,7 +25,7 @@ export const SettingsServerlessFunctionNewForm = ({
|
||||
<TextInput
|
||||
placeholder="Name"
|
||||
fullWidth
|
||||
focused
|
||||
autoFocusOnMount
|
||||
value={formValues.name}
|
||||
onChange={onChange('name')}
|
||||
/>
|
||||
|
||||
@@ -14,7 +14,8 @@ export type TextInputProps = TextInputV2ComponentProps & {
|
||||
disableHotkeys?: boolean;
|
||||
onInputEnter?: () => void;
|
||||
dataTestId?: string;
|
||||
focused?: boolean;
|
||||
autoFocusOnMount?: boolean;
|
||||
autoSelectOnMount?: boolean;
|
||||
};
|
||||
|
||||
export const TextInput = ({
|
||||
@@ -22,7 +23,8 @@ export const TextInput = ({
|
||||
onBlur,
|
||||
onInputEnter,
|
||||
disableHotkeys = false,
|
||||
focused,
|
||||
autoFocusOnMount,
|
||||
autoSelectOnMount,
|
||||
dataTestId,
|
||||
...props
|
||||
}: TextInputProps) => {
|
||||
@@ -31,11 +33,17 @@ export const TextInput = ({
|
||||
const [isFocused, setIsFocused] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (focused === true) {
|
||||
if (autoFocusOnMount === true) {
|
||||
inputRef.current?.focus();
|
||||
setIsFocused(true);
|
||||
}
|
||||
}, [focused]);
|
||||
}, [autoFocusOnMount]);
|
||||
|
||||
useEffect(() => {
|
||||
if (autoSelectOnMount === true) {
|
||||
inputRef.current?.select();
|
||||
}
|
||||
}, [autoSelectOnMount]);
|
||||
|
||||
const {
|
||||
goBackToPreviousHotkeyScope,
|
||||
|
||||
Reference in New Issue
Block a user