-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTypeRichTextInput.tsx
More file actions
128 lines (114 loc) · 3.42 KB
/
TypeRichTextInput.tsx
File metadata and controls
128 lines (114 loc) · 3.42 KB
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
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
import { forwardRef, useImperativeHandle, useRef, type Ref } from 'react';
import type { NativeSyntheticEvent } from 'react-native';
import NativeTypeRichTextInput, {
Commands,
} from './TypeRichTextInputNativeComponent';
import type {
OnChangeSelectionEvent,
OnChangeTextEvent,
onPasteImageEventData,
} from './TypeRichTextInputNativeComponent';
import type {
TypeRichTextInputProps,
TypeRichTextInputRef,
} from './types/TypeRichTextInput';
type MaybeNativeEvent<T> = T | { nativeEvent: T };
export function normalizeEvent<T>(event: MaybeNativeEvent<T>): T {
if (event && typeof event === 'object' && 'nativeEvent' in event) {
return (event as { nativeEvent: T }).nativeEvent;
}
return event as T;
}
/**
* TypeRichTextInput
*
* A high-performance rich text input component with:
* - image pasting support
* - Fabric-based rendering
* - custom ShadowNode on Android
*
* iOS support is currently in Beta Stage
*/
const TypeRichTextInput = forwardRef(
(props: TypeRichTextInputProps, ref: Ref<TypeRichTextInputRef>) => {
const nativeRef = useRef(null);
const { scrollEnabled = true, editable = true, ...restProps } = props;
useImperativeHandle(ref, () => ({
focus: () => {
if (nativeRef.current) {
Commands.focus(nativeRef.current);
}
},
blur: () => {
if (nativeRef.current) {
Commands.blur(nativeRef.current);
}
},
setText: (text: string) => {
if (nativeRef.current) {
Commands.setText(nativeRef.current, text);
}
},
setSelection(start, end) {
if (nativeRef.current) {
Commands.setSelection(nativeRef.current, start, end);
}
},
insertTextAt: (start: number, end: number, text: string) => {
if (nativeRef.current) {
Commands.insertTextAt(nativeRef.current, start, end, text);
}
},
getNativeRef: () => nativeRef.current,
}));
/**
todo: make this only for NativeSyntheticEvent
*/
function handlePasteImage(
event:
| onPasteImageEventData
| { nativeEvent: onPasteImageEventData }
| NativeSyntheticEvent<onPasteImageEventData>
| any
): void {
// always getting nativeevent but will refactor later
const data: onPasteImageEventData | undefined =
event && typeof event === 'object'
? event.nativeEvent ?? event
: undefined;
if (data) {
props.onPasteImageData?.(data as onPasteImageEventData);
}
}
function handleOnChangeTextEvent(
event: OnChangeTextEvent | { nativeEvent: OnChangeTextEvent }
) {
const e = normalizeEvent(event);
props.onChangeText?.(e.value);
}
function handleonChangeSelectionEvent(
event: OnChangeSelectionEvent | { nativeEvent: OnChangeSelectionEvent }
) {
const e = normalizeEvent(event);
props.onChangeSelection?.({
start: e.start,
end: e.end,
text: e.text,
});
}
return (
<NativeTypeRichTextInput
ref={nativeRef}
{...restProps}
scrollEnabled={scrollEnabled}
editable={editable}
onInputFocus={() => props.onFocus?.()}
onInputBlur={() => props.onBlur?.()}
onChangeText={handleOnChangeTextEvent}
onChangeSelection={handleonChangeSelectionEvent}
onPasteImage={handlePasteImage}
/>
);
}
);
export default TypeRichTextInput;