diff --git a/src/components/TextFieldChip/TextFieldChips.test.tsx b/src/components/TextFieldChip/TextFieldChips.test.tsx index e18b8b6..a94cb4e 100644 --- a/src/components/TextFieldChip/TextFieldChips.test.tsx +++ b/src/components/TextFieldChip/TextFieldChips.test.tsx @@ -340,4 +340,21 @@ describe('components/TextFieldChips', () => { expect(screen.getByTestId('EmailIcon')).toBeTruthy() }) + + test('should control the input value', async () => { + const callbackOnInputChange = vi.fn(() => {}) + render( + + ) + + expect(testUtils.getInputElement().value).toBe('Hello world') + + await testUtils.typeInInputElement(' ') + + expect(callbackOnInputChange).toBeCalledWith('Hello world ') + }) }) diff --git a/src/components/TextFieldChip/TextFieldChips.tsx b/src/components/TextFieldChip/TextFieldChips.tsx index d121c50..9d91ec0 100644 --- a/src/components/TextFieldChip/TextFieldChips.tsx +++ b/src/components/TextFieldChip/TextFieldChips.tsx @@ -25,6 +25,7 @@ type TextFieldChipsProps = TextFieldProps & { disableDeleteOnBackspace?: boolean addOnWhichKey?: string | string[] disableEdition?: boolean + inputValue?: string validate?: MuiChipsInputProps['validate'] onInputChange?: (inputValue: string) => void onDeleteChip?: (chipIndex: number) => void @@ -61,11 +62,18 @@ const TextFieldChips = React.forwardRef( className, renderChip, addOnWhichKey, + onFocus, + inputValue: inputValueControlled, ...restTextFieldProps } = props - const [inputValue, setInputValue] = React.useState('') + const [inputValueUncontrolled, setInputValueUncontrolled] = + React.useState('') const [textError, setTextError] = React.useState('') const inputElRef = React.useRef(null) + const isFocusingRef = React.useRef(false) + const isControlledRef = React.useRef( + typeof inputValueControlled === 'string' + ) const [chipIndexEditable, setChipIndexEditable] = React.useState< null | number >(null) @@ -76,9 +84,16 @@ const TextFieldChips = React.forwardRef( setTextError('') } + const isControlled = isControlledRef.current + const inputValue = isControlled + ? (inputValueControlled as string) + : inputValueUncontrolled + const updateInputValue = (newInputValue: string) => { onInputChange?.(newInputValue) - setInputValue(newInputValue) + if (!isControlled) { + setInputValueUncontrolled(newInputValue) + } } const updateChipIndexEditable = (chipIndex: number) => { @@ -101,12 +116,17 @@ const TextFieldChips = React.forwardRef( } const handleClickAway = () => { + if (!isFocusingRef.current) { + return + } if (chipIndexEditable !== null) { clearChipIndexEditable() clearInputValue() } else if (clearInputOnBlur) { clearInputValue() } + + isFocusingRef.current = false } const handleRef = (ref: HTMLDivElement | null): void => { @@ -212,6 +232,12 @@ const TextFieldChips = React.forwardRef( onKeyDown?.(event) } + const handleFocus = (event: React.FocusEvent) => { + event.preventDefault() + onFocus?.(event) + isFocusingRef.current = true + } + const handleClearAll = (event: React.MouseEvent) => { event.preventDefault() if (!hideClearAll && !disabled) { @@ -254,6 +280,7 @@ const TextFieldChips = React.forwardRef( className={`MuiChipsInput-TextField ${className || ''}`} size={size} placeholder="Type and press enter" + onFocus={handleFocus} inputProps={{ onKeyDown: handleKeyDown, ...restInputProps @@ -317,6 +344,7 @@ TextFieldChips.defaultProps = { addOnWhichKey: KEYBOARD_KEY.enter, onDeleteChip: () => {}, onAddChip: () => {}, + inputValue: undefined, onEditChip: () => {}, renderChip: undefined, onDeleteAllChips: () => {}, diff --git a/src/index.tsx b/src/index.tsx index ef0a318..7aa20f2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -34,6 +34,7 @@ const MuiChipsInput = React.forwardRef( renderChip, disableEdition, addOnWhichKey, + inputValue, ...restTextFieldProps } = props as Required @@ -86,6 +87,7 @@ const MuiChipsInput = React.forwardRef( disabled={disabled} disableEdition={disableEdition} validate={validate} + inputValue={inputValue} hideClearAll={hideClearAll} addOnWhichKey={addOnWhichKey} {...restTextFieldProps} diff --git a/src/index.types.ts b/src/index.types.ts index 2d71209..e93b01f 100644 --- a/src/index.types.ts +++ b/src/index.types.ts @@ -27,6 +27,7 @@ export type MuiChipsInputChip = string export interface BaseMuiChipsInputProps { value?: MuiChipsInputChip[] onInputChange?: (inputValue: string) => void + inputValue?: string onAddChip?: (chipValue: MuiChipsInputChip, chipIndex: number) => void onDeleteChip?: (chipValue: MuiChipsInputChip, chipIndex: number) => void onEditChip?: (chipValue: MuiChipsInputChip, chipIndex: number) => void