File tree 3 files changed +60
-0
lines changed
3 files changed +60
-0
lines changed Original file line number Diff line number Diff line change 1
1
import { forwardRef } from 'react'
2
2
import type { DetailedHTMLProps , InputHTMLAttributes } from 'react'
3
3
4
+ import { useInputComposition } from '~/hooks/common/use-input-composition'
4
5
import { clsxm } from '~/lib/helper'
5
6
7
+ // This composition handler is not perfect
8
+ // @see https://foxact.skk.moe/use-composition-input
6
9
export const Input = forwardRef <
7
10
HTMLInputElement ,
8
11
Omit <
9
12
DetailedHTMLProps < InputHTMLAttributes < HTMLInputElement > , HTMLInputElement > ,
10
13
'ref'
11
14
>
12
15
> ( ( { className, ...props } , ref ) => {
16
+ const inputProps = useInputComposition ( props )
13
17
return (
14
18
< input
15
19
ref = { ref }
@@ -21,6 +25,7 @@ export const Input = forwardRef<
21
25
className ,
22
26
) }
23
27
{ ...props }
28
+ { ...inputProps }
24
29
/>
25
30
)
26
31
} )
Original file line number Diff line number Diff line change @@ -7,6 +7,7 @@ import type {
7
7
} from 'react'
8
8
9
9
import { useIsMobile } from '~/atoms'
10
+ import { useInputComposition } from '~/hooks/common/use-input-composition'
10
11
import { clsxm } from '~/lib/helper'
11
12
12
13
export const TextArea = forwardRef <
@@ -30,6 +31,7 @@ export const TextArea = forwardRef<
30
31
)
31
32
const background = useMotionTemplate `radial-gradient(320px circle at ${ mouseX } px ${ mouseY } px, var(--spotlight-color) 0%, transparent 85%)`
32
33
const isMobile = useIsMobile ( )
34
+ const inputProps = useInputComposition ( props )
33
35
return (
34
36
< div
35
37
className = "group relative h-full [--spotlight-color:hsl(var(--a)_/_0.05)]"
@@ -51,6 +53,7 @@ export const TextArea = forwardRef<
51
53
className ,
52
54
) }
53
55
{ ...rest }
56
+ { ...inputProps }
54
57
/>
55
58
56
59
{ children }
Original file line number Diff line number Diff line change
1
+ import { useCallback , useRef } from 'react'
2
+ import type { CompositionEventHandler } from 'react'
3
+
4
+ export const useInputComposition = (
5
+ props :
6
+ | React . DetailedHTMLProps <
7
+ React . InputHTMLAttributes < HTMLInputElement > ,
8
+ HTMLInputElement
9
+ >
10
+ | React . DetailedHTMLProps <
11
+ React . TextareaHTMLAttributes < HTMLTextAreaElement > ,
12
+ HTMLTextAreaElement
13
+ > ,
14
+ ) => {
15
+ const { onKeyDown, onCompositionStart, onCompositionEnd } = props
16
+
17
+ const isCompositionRef = useRef ( false )
18
+
19
+ const handleCompositionStart : CompositionEventHandler < any > = useCallback (
20
+ ( e ) => {
21
+ isCompositionRef . current = true
22
+ onCompositionStart ?.( e )
23
+ } ,
24
+ [ onCompositionStart ] ,
25
+ )
26
+
27
+ const handleCompositionEnd : CompositionEventHandler < any > = useCallback (
28
+ ( e ) => {
29
+ isCompositionRef . current = false
30
+ onCompositionEnd ?.( e )
31
+ } ,
32
+ [ onCompositionEnd ] ,
33
+ )
34
+
35
+ const handleKeyDown : React . KeyboardEventHandler < any > = useCallback (
36
+ ( e ) => {
37
+ onKeyDown ?.( e )
38
+
39
+ if ( isCompositionRef . current ) {
40
+ e . stopPropagation ( )
41
+ return
42
+ }
43
+ } ,
44
+ [ onKeyDown ] ,
45
+ )
46
+
47
+ return {
48
+ onCompositionEnd : handleCompositionEnd ,
49
+ onCompositionStart : handleCompositionStart ,
50
+ onKeyDown : handleKeyDown ,
51
+ }
52
+ }
You can’t perform that action at this time.
0 commit comments