-
Notifications
You must be signed in to change notification settings - Fork 15
/
useTextField.ts
42 lines (35 loc) · 1.32 KB
/
useTextField.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import { InputHTMLAttributes, RefObject, TextareaHTMLAttributes } from 'react'
import { useFocusable } from '../../interactions/focusable'
import { setCursorToEnd } from '../../libs/dom-utils'
import { useIsomorphicLayoutEffect as useLayoutEffect } from '../../libs/isomorphic-layout-effect'
import type { CommonTextFieldProps } from './types'
export interface UseTextFieldResult<T> {
inputProps: T
}
export function useTextField<T extends HTMLInputElement | HTMLTextAreaElement>(
props: CommonTextFieldProps,
inputRef: RefObject<T>,
): T extends HTMLTextAreaElement
? UseTextFieldResult<TextareaHTMLAttributes<T>>
: UseTextFieldResult<InputHTMLAttributes<T>> {
const { as: elementType = 'input', type = 'text', autoComplete = 'off', ...restProps } = props
const { focusableProps } = useFocusable(props, inputRef)
let additionalProps: InputHTMLAttributes<HTMLInputElement> = {}
if (elementType === 'input') {
additionalProps = { type }
}
useLayoutEffect(() => {
// By default autofocus set cursor at start position when element type is textarea.
if (elementType === 'textarea') {
setCursorToEnd(inputRef.current)
}
}, [elementType, inputRef, props.autoFocus])
return {
inputProps: {
autoComplete,
...restProps,
...focusableProps,
...additionalProps,
},
} as any
}