From bebea62901a895c7da9e6f3352194deb9a37dc06 Mon Sep 17 00:00:00 2001 From: Daniel O Date: Fri, 23 Aug 2019 14:12:09 +0300 Subject: [PATCH] feat: [FX-377] Proxy ref from forwardRef to FileInput (#621) --- src/components/FileInput/FileInput.tsx | 14 +++++++---- .../OutlinedInput/OutlinedInput.tsx | 5 +--- src/components/utils/index.ts | 2 ++ src/components/utils/use-combined-refs.ts | 24 +++++++++++++++++++ 4 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 src/components/utils/use-combined-refs.ts diff --git a/src/components/FileInput/FileInput.tsx b/src/components/FileInput/FileInput.tsx index d3f602e996..ba2973331a 100644 --- a/src/components/FileInput/FileInput.tsx +++ b/src/components/FileInput/FileInput.tsx @@ -12,7 +12,7 @@ import Loader from '../Loader' import Link from '../Link' import Typography from '../Typography' import { Check16, UploadDocument16 } from '../Icon' -import { isNumber, isBoolean } from '../utils' +import { isNumber, isBoolean, useCombinedRefs } from '../utils' import styles from './styles' export interface FileInfo { @@ -106,7 +106,12 @@ export const FileInput = forwardRef(function FileInput( }, ref ) { - const nativeInput = useRef() + // if `ref` is null then we need a ref to control the input + // so we create another ref manually if needed and merge both of them + const inputRef = useCombinedRefs( + ref, + useRef(null) + ) const inProgress = (isNumber(progress) && progress! <= 100) || @@ -146,7 +151,7 @@ export const FileInput = forwardRef(function FileInput( size='small' variant={uploadButtonVariant} disabled={disabled} - onClick={() => nativeInput.current && nativeInput.current.click()} + onClick={() => inputRef.current && inputRef.current.click()} > {uploadButtonTitle} @@ -156,7 +161,7 @@ export const FileInput = forwardRef(function FileInput( return ( (function FileInput( accept, status }} - inputRef={nativeInput} startAdornment={startAdornment} endAdornment={endAdornment} /> diff --git a/src/components/OutlinedInput/OutlinedInput.tsx b/src/components/OutlinedInput/OutlinedInput.tsx index c8efa6b2af..46703e4113 100644 --- a/src/components/OutlinedInput/OutlinedInput.tsx +++ b/src/components/OutlinedInput/OutlinedInput.tsx @@ -39,7 +39,6 @@ export interface Props disabled?: boolean inputComponent?: ReactType inputProps?: InputBaseComponentProps - inputRef?: React.Ref | React.RefObject value?: ValueType /** Whether `Input` should be rendered as `TextArea` or not */ multiline?: boolean @@ -74,7 +73,6 @@ const OutlinedInput = forwardRef( disabled, inputComponent, inputProps, - inputRef, value, type, error, @@ -89,7 +87,6 @@ const OutlinedInput = forwardRef( ( error={error} inputComponent={inputComponent} inputProps={inputProps} - inputRef={inputRef} + inputRef={ref} value={value} type={type} startAdornment={startAdornment} diff --git a/src/components/utils/index.ts b/src/components/utils/index.ts index 57287c51c5..274d834d06 100644 --- a/src/components/utils/index.ts +++ b/src/components/utils/index.ts @@ -17,3 +17,5 @@ export { default as isBoolean } from './is-boolean' export { default as isSubstring } from './is-substring' export { Maybe } from './monads' export { useNotifications } from './Notifications' + +export { default as useCombinedRefs } from './use-combined-refs' diff --git a/src/components/utils/use-combined-refs.ts b/src/components/utils/use-combined-refs.ts new file mode 100644 index 0000000000..3cb8a1734e --- /dev/null +++ b/src/components/utils/use-combined-refs.ts @@ -0,0 +1,24 @@ +import { RefObject, Ref, useRef, useEffect } from 'react' + +const useCombinedRefs = (...refs: (RefObject | Ref)[]) => { + const targetRef = useRef(null) + + useEffect(() => { + refs.forEach(ref => { + if (!ref) { + return + } + + if (typeof ref === 'function') { + ref(targetRef.current) + } else { + // @ts-ignore + ref.current = targetRef.current + } + }) + }, [refs]) + + return targetRef +} + +export default useCombinedRefs