@hero-design/rn-work-uikit 1.3.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/lib/index.js +19933 -735
  3. package/package.json +3 -2
  4. package/src/components/DatePicker/__tests__/__snapshots__/index.spec.tsx.snap +3 -3
  5. package/src/components/FormGroup/__tests__/__snapshots__/index.spec.tsx.snap +903 -0
  6. package/src/components/FormGroup/__tests__/index.spec.tsx +306 -0
  7. package/src/components/FormGroup/__tests__/utils.spec.ts +73 -0
  8. package/src/components/FormGroup/index.tsx +106 -0
  9. package/src/components/FormGroup/utils.ts +67 -0
  10. package/src/components/RichTextEditor/EditorEvent.ts +7 -0
  11. package/src/components/RichTextEditor/EditorToolbar.tsx +216 -0
  12. package/src/components/RichTextEditor/MentionList.tsx +99 -0
  13. package/src/components/RichTextEditor/RichTextEditor.tsx +88 -0
  14. package/src/components/RichTextEditor/RichTextEditorInput.tsx +292 -0
  15. package/src/components/RichTextEditor/StyledRichTextEditor.tsx +15 -0
  16. package/src/components/RichTextEditor/StyledToolbar.ts +32 -0
  17. package/src/components/RichTextEditor/__mocks__/hero-editor.js +3 -0
  18. package/src/components/RichTextEditor/__mocks__/heroEditorApp.ts +2 -0
  19. package/src/components/RichTextEditor/__tests__/EditorToolbar.spec.tsx +144 -0
  20. package/src/components/RichTextEditor/__tests__/MentionList.spec.tsx +105 -0
  21. package/src/components/RichTextEditor/__tests__/RichTextEditorInput.spec.tsx +136 -0
  22. package/src/components/RichTextEditor/__tests__/__snapshots__/EditorToolbar.spec.tsx.snap +414 -0
  23. package/src/components/RichTextEditor/__tests__/__snapshots__/MentionList.spec.tsx.snap +13 -0
  24. package/src/components/RichTextEditor/constants.ts +9 -0
  25. package/src/{hero-editor.d.ts → components/RichTextEditor/hero-editor.d.ts} +6 -0
  26. package/src/components/RichTextEditor/heroEditorApp.ts +3 -0
  27. package/src/components/RichTextEditor/index.tsx +20 -0
  28. package/src/components/RichTextEditor/types.ts +87 -0
  29. package/src/components/RichTextEditor/utils/events.ts +31 -0
  30. package/src/components/RichTextEditor/utils/rnWebView.tsx +30 -0
  31. package/src/components/Select/__tests__/__snapshots__/index.spec.tsx.snap +24 -2
  32. package/src/components/Select/index.tsx +11 -10
  33. package/src/components/TextInput/Group/__tests__/__snapshots__/index.spec.tsx.snap +3 -3
  34. package/src/components/TextInput/Group/index.tsx +6 -1
  35. package/src/components/TextInput/InputComponent.tsx +59 -18
  36. package/src/components/TextInput/InputRow.tsx +13 -7
  37. package/src/components/TextInput/StyledTextInput.tsx +3 -3
  38. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +17 -17
  39. package/src/components/TextInput/index.tsx +22 -13
  40. package/src/components/TextInput/types.ts +30 -5
  41. package/src/index.ts +3 -1
  42. package/src/utils/hooks.ts +10 -0
  43. package/stats/1.5.0/rn-work-uikit-stats.html +4844 -0
  44. package/stats/1.3.1/rn-work-uikit-stats.html +0 -4844
@@ -0,0 +1,414 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`EditorToolbar when the editor is focused should render toolbar 1`] = `
4
+ <View
5
+ style={
6
+ [
7
+ [
8
+ {
9
+ "alignItems": "center",
10
+ "backgroundColor": "#f6f6f7",
11
+ "borderTopColor": "#e8e9ea",
12
+ "borderTopWidth": undefined,
13
+ "flexDirection": "row",
14
+ "paddingHorizontal": 7.846153846153847,
15
+ },
16
+ ],
17
+ undefined,
18
+ ]
19
+ }
20
+ testID="toolbar"
21
+ >
22
+ <TouchableOpacity
23
+ onPress={[Function]}
24
+ selected={false}
25
+ style={
26
+ [
27
+ [
28
+ {
29
+ "alignItems": "center",
30
+ "backgroundColor": undefined,
31
+ "height": 47.07692307692308,
32
+ "justifyContent": "center",
33
+ "width": 47.07692307692308,
34
+ },
35
+ ],
36
+ undefined,
37
+ ]
38
+ }
39
+ testID="format-bold"
40
+ >
41
+ <Text
42
+ allowFontScaling={false}
43
+ selectable={false}
44
+ style={
45
+ [
46
+ {
47
+ "color": undefined,
48
+ "fontSize": 12,
49
+ },
50
+ [
51
+ [
52
+ {
53
+ "color": "#001f23",
54
+ "fontSize": 19.615384615384613,
55
+ },
56
+ ],
57
+ undefined,
58
+ ],
59
+ {
60
+ "fontFamily": "hero-icons-mobile",
61
+ "fontStyle": "normal",
62
+ "fontWeight": "normal",
63
+ },
64
+ {},
65
+ ]
66
+ }
67
+ themeIntent="text"
68
+ themeSize="small"
69
+ >
70
+
71
+ </Text>
72
+ </TouchableOpacity>
73
+ <TouchableOpacity
74
+ onPress={[Function]}
75
+ selected={false}
76
+ style={
77
+ [
78
+ [
79
+ {
80
+ "alignItems": "center",
81
+ "backgroundColor": undefined,
82
+ "height": 47.07692307692308,
83
+ "justifyContent": "center",
84
+ "width": 47.07692307692308,
85
+ },
86
+ ],
87
+ undefined,
88
+ ]
89
+ }
90
+ testID="format-italic"
91
+ >
92
+ <Text
93
+ allowFontScaling={false}
94
+ selectable={false}
95
+ style={
96
+ [
97
+ {
98
+ "color": undefined,
99
+ "fontSize": 12,
100
+ },
101
+ [
102
+ [
103
+ {
104
+ "color": "#001f23",
105
+ "fontSize": 19.615384615384613,
106
+ },
107
+ ],
108
+ undefined,
109
+ ],
110
+ {
111
+ "fontFamily": "hero-icons-mobile",
112
+ "fontStyle": "normal",
113
+ "fontWeight": "normal",
114
+ },
115
+ {},
116
+ ]
117
+ }
118
+ themeIntent="text"
119
+ themeSize="small"
120
+ >
121
+
122
+ </Text>
123
+ </TouchableOpacity>
124
+ <TouchableOpacity
125
+ onPress={[Function]}
126
+ selected={false}
127
+ style={
128
+ [
129
+ [
130
+ {
131
+ "alignItems": "center",
132
+ "backgroundColor": undefined,
133
+ "height": 47.07692307692308,
134
+ "justifyContent": "center",
135
+ "width": 47.07692307692308,
136
+ },
137
+ ],
138
+ undefined,
139
+ ]
140
+ }
141
+ testID="format-underlined"
142
+ >
143
+ <Text
144
+ allowFontScaling={false}
145
+ selectable={false}
146
+ style={
147
+ [
148
+ {
149
+ "color": undefined,
150
+ "fontSize": 12,
151
+ },
152
+ [
153
+ [
154
+ {
155
+ "color": "#001f23",
156
+ "fontSize": 19.615384615384613,
157
+ },
158
+ ],
159
+ undefined,
160
+ ],
161
+ {
162
+ "fontFamily": "hero-icons-mobile",
163
+ "fontStyle": "normal",
164
+ "fontWeight": "normal",
165
+ },
166
+ {},
167
+ ]
168
+ }
169
+ themeIntent="text"
170
+ themeSize="small"
171
+ >
172
+
173
+ </Text>
174
+ </TouchableOpacity>
175
+ <View
176
+ style={
177
+ [
178
+ [
179
+ {
180
+ "alignItems": "center",
181
+ "backgroundColor": "#e8e9ea",
182
+ "flexDirection": "row",
183
+ "height": 15.692307692307693,
184
+ "marginHorizontal": 7.846153846153847,
185
+ "width": 1.9615384615384617,
186
+ },
187
+ ],
188
+ undefined,
189
+ ]
190
+ }
191
+ />
192
+ <TouchableOpacity
193
+ onPress={[Function]}
194
+ selected={false}
195
+ style={
196
+ [
197
+ [
198
+ {
199
+ "alignItems": "center",
200
+ "backgroundColor": undefined,
201
+ "height": 47.07692307692308,
202
+ "justifyContent": "center",
203
+ "width": 47.07692307692308,
204
+ },
205
+ ],
206
+ undefined,
207
+ ]
208
+ }
209
+ testID="format-list-bulleted"
210
+ >
211
+ <Text
212
+ allowFontScaling={false}
213
+ selectable={false}
214
+ style={
215
+ [
216
+ {
217
+ "color": undefined,
218
+ "fontSize": 12,
219
+ },
220
+ [
221
+ [
222
+ {
223
+ "color": "#001f23",
224
+ "fontSize": 19.615384615384613,
225
+ },
226
+ ],
227
+ undefined,
228
+ ],
229
+ {
230
+ "fontFamily": "hero-icons-mobile",
231
+ "fontStyle": "normal",
232
+ "fontWeight": "normal",
233
+ },
234
+ {},
235
+ ]
236
+ }
237
+ themeIntent="text"
238
+ themeSize="small"
239
+ >
240
+
241
+ </Text>
242
+ </TouchableOpacity>
243
+ <TouchableOpacity
244
+ onPress={[Function]}
245
+ selected={false}
246
+ style={
247
+ [
248
+ [
249
+ {
250
+ "alignItems": "center",
251
+ "backgroundColor": undefined,
252
+ "height": 47.07692307692308,
253
+ "justifyContent": "center",
254
+ "width": 47.07692307692308,
255
+ },
256
+ ],
257
+ undefined,
258
+ ]
259
+ }
260
+ testID="format-list-numbered"
261
+ >
262
+ <Text
263
+ allowFontScaling={false}
264
+ selectable={false}
265
+ style={
266
+ [
267
+ {
268
+ "color": undefined,
269
+ "fontSize": 12,
270
+ },
271
+ [
272
+ [
273
+ {
274
+ "color": "#001f23",
275
+ "fontSize": 19.615384615384613,
276
+ },
277
+ ],
278
+ undefined,
279
+ ],
280
+ {
281
+ "fontFamily": "hero-icons-mobile",
282
+ "fontStyle": "normal",
283
+ "fontWeight": "normal",
284
+ },
285
+ {},
286
+ ]
287
+ }
288
+ themeIntent="text"
289
+ themeSize="small"
290
+ >
291
+
292
+ </Text>
293
+ </TouchableOpacity>
294
+ <View
295
+ style={
296
+ [
297
+ [
298
+ {
299
+ "alignItems": "center",
300
+ "backgroundColor": "#e8e9ea",
301
+ "flexDirection": "row",
302
+ "height": 15.692307692307693,
303
+ "marginHorizontal": 7.846153846153847,
304
+ "width": 1.9615384615384617,
305
+ },
306
+ ],
307
+ undefined,
308
+ ]
309
+ }
310
+ />
311
+ <TouchableOpacity
312
+ onPress={[Function]}
313
+ selected={false}
314
+ style={
315
+ [
316
+ [
317
+ {
318
+ "alignItems": "center",
319
+ "backgroundColor": undefined,
320
+ "height": 47.07692307692308,
321
+ "justifyContent": "center",
322
+ "width": 47.07692307692308,
323
+ },
324
+ ],
325
+ undefined,
326
+ ]
327
+ }
328
+ testID="format-heading1"
329
+ >
330
+ <Text
331
+ allowFontScaling={false}
332
+ selectable={false}
333
+ style={
334
+ [
335
+ {
336
+ "color": undefined,
337
+ "fontSize": 12,
338
+ },
339
+ [
340
+ [
341
+ {
342
+ "color": "#001f23",
343
+ "fontSize": 19.615384615384613,
344
+ },
345
+ ],
346
+ undefined,
347
+ ],
348
+ {
349
+ "fontFamily": "hero-icons-mobile",
350
+ "fontStyle": "normal",
351
+ "fontWeight": "normal",
352
+ },
353
+ {},
354
+ ]
355
+ }
356
+ themeIntent="text"
357
+ themeSize="small"
358
+ >
359
+
360
+ </Text>
361
+ </TouchableOpacity>
362
+ <TouchableOpacity
363
+ onPress={[Function]}
364
+ selected={false}
365
+ style={
366
+ [
367
+ [
368
+ {
369
+ "alignItems": "center",
370
+ "backgroundColor": undefined,
371
+ "height": 47.07692307692308,
372
+ "justifyContent": "center",
373
+ "width": 47.07692307692308,
374
+ },
375
+ ],
376
+ undefined,
377
+ ]
378
+ }
379
+ testID="format-heading2"
380
+ >
381
+ <Text
382
+ allowFontScaling={false}
383
+ selectable={false}
384
+ style={
385
+ [
386
+ {
387
+ "color": undefined,
388
+ "fontSize": 12,
389
+ },
390
+ [
391
+ [
392
+ {
393
+ "color": "#001f23",
394
+ "fontSize": 19.615384615384613,
395
+ },
396
+ ],
397
+ undefined,
398
+ ],
399
+ {
400
+ "fontFamily": "hero-icons-mobile",
401
+ "fontStyle": "normal",
402
+ "fontWeight": "normal",
403
+ },
404
+ {},
405
+ ]
406
+ }
407
+ themeIntent="text"
408
+ themeSize="small"
409
+ >
410
+
411
+ </Text>
412
+ </TouchableOpacity>
413
+ </View>
414
+ `;
@@ -0,0 +1,13 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`MentionList when search string is not empty should render mention list showing filtered results 1`] = `
4
+ <View>
5
+ <View>
6
+ <Text
7
+ onPress={[Function]}
8
+ >
9
+ Hieu Pham
10
+ </Text>
11
+ </View>
12
+ </View>
13
+ `;
@@ -0,0 +1,9 @@
1
+ export enum ToolbarEvents {
2
+ Bold = 'bold',
3
+ Italic = 'italic',
4
+ Underline = 'underline',
5
+ BulletedList = 'bulleted-list',
6
+ NumberedList = 'numbered-list',
7
+ HeadingOne = 'heading-one',
8
+ HeadingTwo = 'heading-two',
9
+ }
@@ -5,4 +5,10 @@ declare module 'hero-editor/dist/app.js' {
5
5
 
6
6
  declare module 'hero-editor' {
7
7
  export function isEmptyContent(content: unknown): boolean;
8
+ export function plainSerializer(
9
+ content: {
10
+ type: string;
11
+ children: unknown;
12
+ }[]
13
+ ): string;
8
14
  }
@@ -0,0 +1,3 @@
1
+ import * as heroEditorApp from 'hero-editor/dist/app.js';
2
+
3
+ export default heroEditorApp;
@@ -0,0 +1,20 @@
1
+ import React, { forwardRef } from 'react';
2
+ import RichTextEditor, {
3
+ RichTextEditorProps,
4
+ RichTextEditorRef,
5
+ } from './RichTextEditor';
6
+ import MentionList from './MentionList';
7
+
8
+ import Toolbar from './EditorToolbar';
9
+
10
+ const RichTextEditorWithRef = forwardRef<
11
+ RichTextEditorRef,
12
+ Omit<RichTextEditorProps, 'forwardedRef'>
13
+ >((props, ref) => <RichTextEditor {...props} forwardedRef={ref} />);
14
+
15
+ RichTextEditorWithRef.displayName = 'RichTextEditor';
16
+
17
+ export default Object.assign(RichTextEditorWithRef, {
18
+ MentionList,
19
+ Toolbar,
20
+ });
@@ -0,0 +1,87 @@
1
+ import type { StyleProp, ViewStyle } from 'react-native';
2
+
3
+ import { Ref } from 'react';
4
+ import type { TextInputProps } from '../TextInput';
5
+
6
+ export type ToolbarButtonName =
7
+ | 'bold'
8
+ | 'italic'
9
+ | 'underline'
10
+ | 'bulletedList'
11
+ | 'numberedList'
12
+ | 'headingOne'
13
+ | 'headingTwo'
14
+ | '|';
15
+
16
+ export type TextUnit = 'character' | 'word' | 'line' | 'block';
17
+
18
+ export interface RichTextEditorRef {
19
+ requestBlur: VoidFunction;
20
+ insertNodes: (nodes: Record<string, unknown>[]) => void;
21
+ deleteBackward: (unit?: TextUnit) => void;
22
+ setReadOnly: (readOnly: boolean) => void;
23
+ }
24
+
25
+ export type EditorValue = {
26
+ type: string;
27
+ children: unknown;
28
+ }[];
29
+
30
+ export interface RichTextEditorProps {
31
+ /**
32
+ * If true, the editor will be focused when the user enters the screen
33
+ */
34
+ autoFocus?: boolean;
35
+ /**
36
+ * Error message
37
+ */
38
+ error?: string;
39
+ /**
40
+ * Field value
41
+ */
42
+ value?: EditorValue;
43
+ /**
44
+ * Unique name used to communicate with webview
45
+ */
46
+ name: string;
47
+ /**
48
+ * Callback function called when the field value changed
49
+ */
50
+ onChange: (data: EditorValue) => void;
51
+ /**
52
+ * Callback function called when the cursor position changed
53
+ */
54
+ onCursorChange?: (params: { position: { top: number } }) => void;
55
+ /**
56
+ * Field placeholder
57
+ */
58
+ placeholder?: string;
59
+ /**
60
+ * Additional styles
61
+ */
62
+ style?: StyleProp<ViewStyle>;
63
+ /**
64
+ * Field label
65
+ */
66
+ label: string;
67
+ /**
68
+ * Field helper text
69
+ */
70
+ helpText?: string;
71
+ /**
72
+ * Whether the input is required, if true, an asterisk will be appended to the label.
73
+ * */
74
+ required?: boolean;
75
+ /**
76
+ * Testing ID of the component
77
+ */
78
+ testID?: string;
79
+ /**
80
+ * Imperative ref to expose the component method
81
+ */
82
+ forwardedRef?: Ref<RichTextEditorRef>;
83
+ }
84
+
85
+ export interface InternalRichTextEditorProps extends RichTextEditorProps {
86
+ TextInputComponent?: React.ComponentType<TextInputProps>;
87
+ }
@@ -0,0 +1,31 @@
1
+ import { EventEmitter } from 'events';
2
+
3
+ export interface Listener<T> {
4
+ (data: T): void;
5
+ }
6
+
7
+ export const off = <T>(
8
+ emitter: EventEmitter,
9
+ eventName: string,
10
+ listener: Listener<T>
11
+ ) => {
12
+ emitter.off(eventName, listener);
13
+ };
14
+
15
+ export const emit = <T>(emitter: EventEmitter, eventName: string, data: T) =>
16
+ emitter.emit(eventName, data);
17
+
18
+ export const setMaxListeners = (emitter: EventEmitter, n: number) => {
19
+ emitter.setMaxListeners(n);
20
+ };
21
+
22
+ export const on = <T>(
23
+ emitter: EventEmitter,
24
+ eventName: string,
25
+ listener: Listener<T>
26
+ ) => {
27
+ emitter.on(eventName, listener);
28
+ return () => {
29
+ emitter.off(eventName, listener);
30
+ };
31
+ };
@@ -0,0 +1,30 @@
1
+ import WebView from 'react-native-webview';
2
+
3
+ export const requestBlurEditor = (element: WebView): void => {
4
+ element.injectJavaScript(
5
+ '\n window.document.activeElement && window.document.activeElement.blur();\n '
6
+ );
7
+ };
8
+
9
+ export const requestFocusEditor = (element: WebView): void => {
10
+ element.injectJavaScript(
11
+ `
12
+ \n
13
+ var el = window.document.querySelector('[role="textbox"]');
14
+ if (el) el.focus();
15
+ \n
16
+ `
17
+ );
18
+ };
19
+
20
+ export interface WebViewEventMessage {
21
+ type: string;
22
+ data: unknown;
23
+ }
24
+ export const postMessage = (
25
+ element: WebView,
26
+ message: WebViewEventMessage
27
+ ): void => {
28
+ const messageString = JSON.stringify(message);
29
+ element.injectJavaScript(`window.postMessage(${messageString}, '*');`);
30
+ };
@@ -7,6 +7,17 @@ exports[`MultiSelect renders correctly (snapshot) 1`] = `
7
7
  >
8
8
  <TouchableOpacity
9
9
  onPress={[Function]}
10
+ style={
11
+ [
12
+ [
13
+ {},
14
+ ],
15
+ undefined,
16
+ ]
17
+ }
18
+ testID="multi-select-touchable-opacity"
19
+ themeGroupStyleEnabled={false}
20
+ themeHasError={false}
10
21
  >
11
22
  <View
12
23
  pointerEvents="none"
@@ -34,8 +45,8 @@ exports[`MultiSelect renders correctly (snapshot) 1`] = `
34
45
  ]
35
46
  }
36
47
  themeFocused={false}
48
+ themeGroupStyleEnabled={false}
37
49
  themeHasError={false}
38
- themeUseGroupStyleEnabled={false}
39
50
  >
40
51
  <View
41
52
  pointerEvents="none"
@@ -693,6 +704,17 @@ exports[`Select renders correctly (snapshot) 1`] = `
693
704
  >
694
705
  <TouchableOpacity
695
706
  onPress={[Function]}
707
+ style={
708
+ [
709
+ [
710
+ {},
711
+ ],
712
+ undefined,
713
+ ]
714
+ }
715
+ testID="single-select-touchable-opacity"
716
+ themeGroupStyleEnabled={false}
717
+ themeHasError={false}
696
718
  >
697
719
  <View
698
720
  pointerEvents="none"
@@ -720,8 +742,8 @@ exports[`Select renders correctly (snapshot) 1`] = `
720
742
  ]
721
743
  }
722
744
  themeFocused={false}
745
+ themeGroupStyleEnabled={false}
723
746
  themeHasError={false}
724
- themeUseGroupStyleEnabled={false}
725
747
  >
726
748
  <View
727
749
  pointerEvents="none"