@hero-design/rn-work-uikit 1.9.4 → 1.9.6

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 (41) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/assets/fonts/hero-icons-mobile.ttf +0 -0
  3. package/es/index.js +69810 -0
  4. package/lib/index.js +809 -440
  5. package/package.json +5 -5
  6. package/src/components/RichTextEditor/MentionList.tsx +2 -1
  7. package/testUtils/renderWithTheme.tsx +2 -2
  8. package/types/index.d.ts +525 -0
  9. package/src/__tests__/index-export.spec.ts +0 -64
  10. package/src/__tests__/index.spec.tsx +0 -14
  11. package/src/components/DatePicker/__tests__/__snapshots__/index.spec.tsx.snap +0 -1649
  12. package/src/components/DatePicker/__tests__/index.spec.tsx +0 -56
  13. package/src/components/FormGroup/__tests__/__snapshots__/index.spec.tsx.snap +0 -908
  14. package/src/components/FormGroup/__tests__/index.spec.tsx +0 -319
  15. package/src/components/FormGroup/__tests__/utils.spec.ts +0 -73
  16. package/src/components/RichTextEditor/__tests__/EditorToolbar.spec.tsx +0 -154
  17. package/src/components/RichTextEditor/__tests__/MentionList.spec.tsx +0 -105
  18. package/src/components/RichTextEditor/__tests__/RichTextEditor.spec.tsx +0 -81
  19. package/src/components/RichTextEditor/__tests__/RichTextEditorInput.spec.tsx +0 -174
  20. package/src/components/RichTextEditor/__tests__/__snapshots__/EditorToolbar.spec.tsx.snap +0 -407
  21. package/src/components/RichTextEditor/__tests__/__snapshots__/MentionList.spec.tsx.snap +0 -13
  22. package/src/components/Select/__tests__/__snapshots__/index.spec.tsx.snap +0 -1324
  23. package/src/components/Select/__tests__/index.spec.tsx +0 -43
  24. package/src/components/TextInput/__tests__/ErrorOrHelpText.spec.tsx +0 -20
  25. package/src/components/TextInput/__tests__/FloatingLabel.spec.tsx +0 -193
  26. package/src/components/TextInput/__tests__/InputComponent.spec.tsx +0 -41
  27. package/src/components/TextInput/__tests__/InputRow.spec.tsx +0 -233
  28. package/src/components/TextInput/__tests__/MaxLengthMessage.spec.tsx +0 -17
  29. package/src/components/TextInput/__tests__/PrefixComponent.spec.tsx +0 -14
  30. package/src/components/TextInput/__tests__/StyledTextInput.spec.tsx +0 -114
  31. package/src/components/TextInput/__tests__/SuffixComponent.spec.tsx +0 -20
  32. package/src/components/TextInput/__tests__/__snapshots__/StyledTextInput.spec.tsx.snap +0 -583
  33. package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +0 -5835
  34. package/src/components/TextInput/__tests__/getState.spec.tsx +0 -89
  35. package/src/components/TextInput/__tests__/index.spec.tsx +0 -679
  36. package/src/components/TimePicker/__tests__/index.spec.tsx +0 -34
  37. package/src/theme/__tests__/ThemeProvider.spec.tsx +0 -32
  38. package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +0 -2042
  39. package/src/theme/__tests__/index.spec.ts +0 -7
  40. package/src/utils/__tests__/helpers.spec.ts +0 -92
  41. package/stats/1.3.0/rn-work-uikit-stats.html +0 -4842
@@ -1,319 +0,0 @@
1
- import React from 'react';
2
- import { within } from '@testing-library/react-native';
3
- import theme from '../../../theme';
4
- import TextInput from '../../TextInput';
5
- import Select from '../../Select';
6
- import DatePicker from '../../DatePicker';
7
- import TimePicker from '../../TimePicker';
8
- import RichTextEditor from '../../RichTextEditor';
9
- import FormGroup from '..';
10
- import renderWithTheme from '../../../../testUtils/renderWithTheme';
11
- import { noop } from '../../../utils/functions';
12
-
13
- describe('FormGroup', () => {
14
- it('should render', () => {
15
- const { getByText, getByTestId, toJSON } = renderWithTheme(
16
- <FormGroup>
17
- <TextInput label="Text Input 1" value="Text Input 1" required />
18
- <TextInput
19
- label="Text Input 2"
20
- value="Text Input 2"
21
- error="This is an error"
22
- testID="text-input-2"
23
- />
24
- <TextInput label="Text Input 3" value="Text Input 3" required />
25
- </FormGroup>
26
- );
27
-
28
- expect(toJSON()).toMatchSnapshot('xxx');
29
-
30
- expect(getByText('Text Input 1')).toBeVisible();
31
- expect(getByText('Text Input 2', { exact: false })).toBeVisible();
32
- expect(
33
- within(getByTestId('text-input-2')).getByText('(Optional)', {
34
- exact: false,
35
- })
36
- ).toBeVisible();
37
- expect(getByText('This is an error')).toBeVisible();
38
- expect(getByText('Text Input 3')).toBeVisible();
39
- });
40
-
41
- it('renders with correct border styling', () => {
42
- const { getByTestId } = renderWithTheme(
43
- <FormGroup>
44
- <TextInput value="Text Input 1" testID="text-input-1" />
45
- <TextInput value="Text Input 2" testID="text-input-2" />
46
- <TextInput value="Text Input 3" testID="text-input-3" />
47
- </FormGroup>
48
- );
49
-
50
- expect(
51
- within(getByTestId('text-input-1'))
52
- .getByTestId('text-input-border')
53
- .props.style.flat()
54
- ).toEqual(
55
- expect.arrayContaining([
56
- expect.objectContaining({
57
- borderBottomLeftRadius: 0,
58
- borderBottomRightRadius: 0,
59
- }),
60
- ])
61
- );
62
-
63
- expect(
64
- within(getByTestId('text-input-2'))
65
- .getByTestId('text-input-border')
66
- .props.style.flat()
67
- ).toEqual(
68
- expect.arrayContaining([
69
- expect.objectContaining({
70
- borderRadius: 0,
71
- }),
72
- ])
73
- );
74
-
75
- expect(
76
- within(getByTestId('text-input-3'))
77
- .getByTestId('text-input-border')
78
- .props.style.flat()
79
- ).toEqual(
80
- expect.arrayContaining([
81
- expect.objectContaining({
82
- borderTopLeftRadius: 0,
83
- borderTopRightRadius: 0,
84
- }),
85
- ])
86
- );
87
- });
88
-
89
- it('merges with the children styles in correct order', () => {
90
- const { getByTestId } = renderWithTheme(
91
- <FormGroup>
92
- <TextInput
93
- value="Text Input 1"
94
- testID="text-input-1"
95
- textStyle={{
96
- borderColor: '#ffffff',
97
- borderWidth: 1,
98
- }}
99
- />
100
- <TextInput
101
- value="Text Input 2"
102
- testID="text-input-2"
103
- style={{ width: 300 }}
104
- />
105
- </FormGroup>
106
- );
107
-
108
- // Merging text styles
109
- expect(
110
- within(getByTestId('text-input-1'))
111
- .getByTestId('text-input-border')
112
- .props.style.flat()
113
- ).toEqual(
114
- expect.arrayContaining([
115
- expect.objectContaining({
116
- // Passed style
117
- borderWidth: 1,
118
- borderColor: '#ffffff',
119
- // Injected style
120
- borderBottomLeftRadius: 0,
121
- borderBottomRightRadius: 0,
122
- }),
123
- ])
124
- );
125
-
126
- // Merging container styles
127
- expect(getByTestId('text-input-2').props.style.flat()).toEqual(
128
- expect.arrayContaining([
129
- expect.objectContaining({
130
- // Passed style
131
- width: 300,
132
- // Injected style
133
- marginTop: -theme.__hd__.textInput.borderWidths.container.normal,
134
- }),
135
- ])
136
- );
137
-
138
- expect(
139
- within(getByTestId('text-input-2'))
140
- .getByTestId('text-input-border')
141
- .props.style.flat()
142
- ).toEqual(
143
- expect.arrayContaining([
144
- expect.objectContaining({
145
- // Injected style
146
- borderTopLeftRadius: 0,
147
- borderTopRightRadius: 0,
148
- }),
149
- ])
150
- );
151
- });
152
-
153
- it('does not alter the children styles if there is only one child', () => {
154
- const { getByTestId } = renderWithTheme(
155
- <FormGroup>
156
- <TextInput
157
- value="Text Input 1"
158
- testID="text-input-1"
159
- style={{
160
- marginTop: theme.space.medium,
161
- }}
162
- />
163
- </FormGroup>
164
- );
165
-
166
- // Container style is not injected
167
- expect(getByTestId('text-input-1').props.style.flat()).toEqual(
168
- expect.arrayContaining([
169
- expect.objectContaining({
170
- // Passed style instead of injected style
171
- marginTop: theme.space.medium,
172
- }),
173
- ])
174
- );
175
-
176
- // Border style is not injected
177
- const internalBorderStyle =
178
- getByTestId('text-input-border').props.style.flat();
179
- const borderKeys = Object.keys(internalBorderStyle).filter((key) =>
180
- key.startsWith('border')
181
- );
182
- expect(borderKeys).toHaveLength(0);
183
- });
184
-
185
- it('renders all component types (TextInput, Select, Select.Multi, DatePicker, TimePicker, RichTextEditor) with correct styles', () => {
186
- const { getByTestId } = renderWithTheme(
187
- <FormGroup>
188
- <TextInput
189
- label="Text Input"
190
- value="Text Input"
191
- testID="mixed-text-input"
192
- />
193
- <DatePicker
194
- label="Date Picker"
195
- value={new Date('1995-12-17T00:00:00.000Z')}
196
- testID="mixed-date-picker"
197
- onChange={noop}
198
- confirmLabel="Confirm"
199
- />
200
- <TimePicker
201
- label="Time Picker"
202
- value={new Date('December 17, 1995 03:24:00')}
203
- testID="mixed-time-picker"
204
- onChange={noop}
205
- confirmLabel="Confirm"
206
- />
207
- <RichTextEditor
208
- label="Rich Text Editor"
209
- value={[{ type: 'paragraph', children: [{ text: 'Content' }] }]}
210
- onChange={noop}
211
- name="mixed-rich-text-editor"
212
- testID="mixed-rich-text-editor"
213
- />
214
- <Select
215
- label="Single Select"
216
- value="option1"
217
- testID="mixed-select"
218
- onConfirm={noop}
219
- options={[
220
- { text: 'Option 1', value: 'option1' },
221
- { text: 'Option 2', value: 'option2' },
222
- ]}
223
- />
224
- <Select.Multi
225
- label="Multi Select"
226
- value={['option1', 'option2']}
227
- testID="mixed-select-multi"
228
- onConfirm={noop}
229
- footerLabel="Confirm"
230
- options={[
231
- { text: 'Option 1', value: 'option1' },
232
- { text: 'Option 2', value: 'option2' },
233
- { text: 'Option 3', value: 'option3' },
234
- ]}
235
- />
236
- </FormGroup>
237
- );
238
-
239
- // TextInput should have top border radius removed (first component)
240
- expect(
241
- within(getByTestId('mixed-text-input'))
242
- .getByTestId('text-input-border')
243
- .props.style.flat()
244
- ).toEqual(
245
- expect.arrayContaining([
246
- expect.objectContaining({
247
- borderBottomLeftRadius: 0,
248
- borderBottomRightRadius: 0,
249
- }),
250
- ])
251
- );
252
-
253
- // DatePicker should have no border radius (middle component)
254
- expect(
255
- within(getByTestId('mixed-date-picker'))
256
- .getByTestId('text-input-border')
257
- .props.style.flat()
258
- ).toEqual(
259
- expect.arrayContaining([
260
- expect.objectContaining({
261
- borderRadius: 0,
262
- }),
263
- ])
264
- );
265
-
266
- // TimePicker should have no border radius (middle component)
267
- expect(
268
- within(getByTestId('mixed-time-picker'))
269
- .getByTestId('text-input-border')
270
- .props.style.flat()
271
- ).toEqual(
272
- expect.arrayContaining([
273
- expect.objectContaining({
274
- borderRadius: 0,
275
- }),
276
- ])
277
- );
278
-
279
- // RichTextEditor should have no border radius (middle component)
280
- expect(
281
- within(getByTestId('mixed-rich-text-editor'))
282
- .getByTestId('text-input-border')
283
- .props.style.flat()
284
- ).toEqual(
285
- expect.arrayContaining([
286
- expect.objectContaining({
287
- borderRadius: 0,
288
- }),
289
- ])
290
- );
291
-
292
- // Select should have no border radius (middle component)
293
- expect(
294
- within(getByTestId('mixed-select'))
295
- .getByTestId('text-input-border')
296
- .props.style.flat()
297
- ).toEqual(
298
- expect.arrayContaining([
299
- expect.objectContaining({
300
- borderRadius: 0,
301
- }),
302
- ])
303
- );
304
-
305
- // Select.Multi should have bottom border radius removed (last component)
306
- expect(
307
- within(getByTestId('mixed-select-multi'))
308
- .getByTestId('text-input-border')
309
- .props.style.flat()
310
- ).toEqual(
311
- expect.arrayContaining([
312
- expect.objectContaining({
313
- borderTopLeftRadius: 0,
314
- borderTopRightRadius: 0,
315
- }),
316
- ])
317
- );
318
- });
319
- });
@@ -1,73 +0,0 @@
1
- import theme from '../../../theme';
2
- import { generateBorderStyle, generateMarginStyle } from '../utils';
3
-
4
- describe('utils', () => {
5
- describe('generateBorderStyle', () => {
6
- it('should generate the correct border style for the first child', () => {
7
- const borderStyle = generateBorderStyle({ index: 0, length: 3 });
8
- expect(borderStyle).toEqual({
9
- borderBottomLeftRadius: 0,
10
- borderBottomRightRadius: 0,
11
- });
12
- });
13
-
14
- it('should generate the correct border style for the last child', () => {
15
- const borderStyle = generateBorderStyle({ index: 2, length: 3 });
16
- expect(borderStyle).toEqual({
17
- borderTopLeftRadius: 0,
18
- borderTopRightRadius: 0,
19
- });
20
- });
21
-
22
- it('should generate the correct border style for the middle child', () => {
23
- const borderStyle = generateBorderStyle({ index: 1, length: 3 });
24
- expect(borderStyle).toEqual({
25
- borderRadius: 0,
26
- });
27
- });
28
- });
29
-
30
- describe('generateMarginStyle', () => {
31
- it('should generate the correct margin style for the first child', () => {
32
- const marginStyle = generateMarginStyle({
33
- index: 0,
34
- length: 3,
35
- theme,
36
- });
37
- expect(marginStyle).toEqual({
38
- marginTop: 0,
39
- });
40
- });
41
-
42
- it('should generate the correct margin style for the last child', () => {
43
- const marginStyle = generateMarginStyle({
44
- index: 2,
45
- length: 3,
46
- theme,
47
- });
48
- expect(marginStyle).toEqual({
49
- marginTop: -theme.__hd__.textInput.borderWidths.container.normal,
50
- });
51
- });
52
-
53
- it('should generate the correct margin style for the middle child', () => {
54
- const marginStyle = generateMarginStyle({
55
- index: 1,
56
- length: 3,
57
- theme,
58
- });
59
- expect(marginStyle).toEqual({
60
- marginTop: -theme.__hd__.textInput.borderWidths.container.normal,
61
- });
62
- });
63
-
64
- it('should generate the correct margin style for a single child', () => {
65
- const marginStyle = generateMarginStyle({
66
- index: 0,
67
- length: 1,
68
- theme,
69
- });
70
- expect(marginStyle).toEqual({});
71
- });
72
- });
73
- });
@@ -1,154 +0,0 @@
1
- import React from 'react';
2
- import { act, fireEvent, waitFor } from '@testing-library/react-native';
3
- import type { RenderAPI } from '@testing-library/react-native';
4
- import EditorToolbar from '../EditorToolbar';
5
- import { emitter as editorEventEmitter } from '../EditorEvent';
6
- import renderWithTheme from '../../../../testUtils/renderWithTheme';
7
- import { theme } from '../../../index';
8
- import * as Events from '../utils/events';
9
-
10
- describe('EditorToolbar', () => {
11
- it('should not render toolbar when the editor is not focused', () => {
12
- const wrapper = renderWithTheme(
13
- <EditorToolbar testID="editor-toolbar" name="toolbar" />
14
- );
15
- const toolbar = wrapper.queryByTestId('editor-toolbar');
16
- expect(toolbar).toBeNull();
17
- });
18
-
19
- describe('when the editor is focused', () => {
20
- let wrapper: RenderAPI;
21
-
22
- beforeEach(async () => {
23
- wrapper = renderWithTheme(
24
- <EditorToolbar name="toolbar" testID="toolbar" />
25
- );
26
- act(() => {
27
- editorEventEmitter.emit('toolbar/editor-focus');
28
- });
29
- await waitFor(() => wrapper.getByTestId('toolbar'));
30
- });
31
-
32
- it('should render toolbar', async () => {
33
- expect(wrapper.toJSON()).toMatchSnapshot();
34
-
35
- [
36
- 'format-bold',
37
- 'format-italic',
38
- 'format-underlined',
39
- 'format-list-bulleted',
40
- 'format-list-numbered',
41
- 'format-heading1',
42
- 'format-heading2',
43
- ].forEach((testId) => {
44
- expect(wrapper.queryAllByTestId(testId)).toHaveLength(1);
45
- });
46
- });
47
-
48
- it('should hide toolbar when blur', async () => {
49
- act(() => {
50
- editorEventEmitter.emit('toolbar/editor-blur');
51
- });
52
- await waitFor(() => wrapper.queryAllByTestId('toolbar').length === 0);
53
- expect(wrapper.queryAllByTestId('toolbar')).toHaveLength(0);
54
- });
55
-
56
- describe("should change button's background color when pressing", () => {
57
- it('should send event and highlight buttons correctly', () => {
58
- const emittedEvents: string[] = [];
59
-
60
- const eventNameAndTestIDArray = [
61
- {
62
- eventName: 'toolbar/bold',
63
- testID: 'format-bold',
64
- },
65
- {
66
- eventName: 'toolbar/italic',
67
- testID: 'format-italic',
68
- },
69
- {
70
- eventName: 'toolbar/underline',
71
- testID: 'format-underlined',
72
- },
73
- {
74
- eventName: 'toolbar/bulleted-list',
75
- testID: 'format-list-bulleted',
76
- },
77
- {
78
- eventName: 'toolbar/numbered-list',
79
- testID: 'format-list-numbered',
80
- },
81
- {
82
- eventName: 'toolbar/heading-one',
83
- testID: 'format-heading1',
84
- },
85
- {
86
- eventName: 'toolbar/heading-two',
87
- testID: 'format-heading2',
88
- },
89
- ];
90
-
91
- eventNameAndTestIDArray.forEach(({ eventName, testID }) => {
92
- Events.on(editorEventEmitter, eventName, () => {
93
- emittedEvents.push(testID);
94
- });
95
-
96
- expect(wrapper.getByTestId(testID)).toHaveStyle({
97
- backgroundColor: undefined,
98
- });
99
-
100
- fireEvent(wrapper.getByTestId(testID), 'press');
101
- });
102
-
103
- const standaloneButtonTestIDs = [
104
- 'format-list-bulleted',
105
- 'format-list-numbered',
106
- 'format-heading1',
107
- ];
108
- standaloneButtonTestIDs.forEach((testID) => {
109
- expect(wrapper.getByTestId(testID)).toHaveStyle({
110
- backgroundColor: undefined,
111
- });
112
- });
113
-
114
- expect(emittedEvents).toMatchObject([
115
- 'format-bold',
116
- 'format-italic',
117
- 'format-underlined',
118
- 'format-list-bulleted',
119
- 'format-list-numbered',
120
- 'format-heading1',
121
- 'format-heading2',
122
- ]);
123
- });
124
-
125
- it('should highlight buttons correctly', async () => {
126
- act(() => {
127
- editorEventEmitter.emit('toolbar/editor-change', {
128
- toolbarState: {
129
- bold: true,
130
- italic: true,
131
- underline: true,
132
- 'heading-one': true,
133
- },
134
- });
135
- });
136
-
137
- [
138
- 'format-bold',
139
- 'format-italic',
140
- 'format-underlined',
141
- 'format-heading1',
142
- ].forEach(async (testID) => {
143
- await waitFor(() => {
144
- expect(wrapper.getByTestId(testID)).toHaveStyle({
145
- backgroundColor:
146
- theme.__hd__.richTextEditor.colors
147
- .toolbarButtonSelectedBackground,
148
- });
149
- });
150
- });
151
- });
152
- });
153
- });
154
- });
@@ -1,105 +0,0 @@
1
- import type { RenderAPI } from '@testing-library/react-native';
2
- import { act, fireEvent, render } from '@testing-library/react-native';
3
- import React from 'react';
4
- import { Text, View } from 'react-native';
5
- import { emitter as editorEventEmitter } from '../EditorEvent';
6
- import MentionList from '../MentionList';
7
- import * as Events from '../utils/events';
8
- import renderWithTheme from '../../../../testUtils/renderWithTheme';
9
-
10
- const SuggestionListData: Array<{ id: string; name: string }> = [
11
- { id: '1', name: 'Kien Tran' },
12
- { id: '2', name: 'Minh Dinh' },
13
- { id: '3', name: 'Hieu Pham' },
14
- { id: '4', name: 'Hau' },
15
- { id: '5', name: 'Tung Ten' },
16
- { id: '6', name: 'Thong Quach' },
17
- ];
18
-
19
- const SuggestionList = ({
20
- searchValue,
21
- onSelect,
22
- }: {
23
- searchValue: string;
24
- onSelect: (id: string, name: string) => void;
25
- }) => {
26
- const filteredData = SuggestionListData.filter((item) =>
27
- item.name.includes(searchValue)
28
- );
29
-
30
- return (
31
- <View>
32
- {filteredData.map((item) => (
33
- <Text key={item.id} onPress={() => onSelect(item.id, item.name)}>
34
- {item.name}
35
- </Text>
36
- ))}
37
- </View>
38
- );
39
- };
40
-
41
- describe('MentionList', () => {
42
- describe('when search string is empty', () => {
43
- it('should not render mention list', () => {
44
- const wrapper = render(
45
- <MentionList
46
- name="give-shout-out"
47
- render={() => <Text>Mention List</Text>}
48
- />
49
- );
50
-
51
- expect(wrapper.toJSON()).toBeNull();
52
- });
53
- });
54
-
55
- describe('when search string is not empty', () => {
56
- let wrapper: RenderAPI;
57
-
58
- beforeEach(async () => {
59
- wrapper = renderWithTheme(
60
- <MentionList
61
- name="give-shout-out"
62
- render={(
63
- searchValue: string,
64
- onSelect: (id: string, name: string) => void
65
- ) => <SuggestionList searchValue={searchValue} onSelect={onSelect} />}
66
- />
67
- );
68
- await act(() => {
69
- editorEventEmitter.emit('give-shout-out/mention-search', {
70
- search: 'Hieu',
71
- target: 'give-shout-out',
72
- });
73
- });
74
- });
75
-
76
- it('should render mention list showing filtered results', async () => {
77
- expect(wrapper.toJSON()).toMatchSnapshot();
78
- expect(wrapper.queryAllByText('Hieu Pham')).toHaveLength(1);
79
- expect(wrapper.queryAllByText('Kien Tran')).toHaveLength(0);
80
- expect(wrapper.queryAllByText('Minh Dinh')).toHaveLength(0);
81
- expect(wrapper.queryAllByText('Hau')).toHaveLength(0);
82
- expect(wrapper.queryAllByText('Tung Teng')).toHaveLength(0);
83
- expect(wrapper.queryAllByText('Thong Quach')).toHaveLength(0);
84
- });
85
-
86
- describe('onPress suggesstion item', () => {
87
- it('should emit action metion-only', () => {
88
- const result: { id: string; name: string; target: string }[] = [];
89
- act(() => {
90
- Events.on(
91
- editorEventEmitter,
92
- 'give-shout-out/mention-apply',
93
- (data: { id: string; name: string; target: string }) => {
94
- result.push(data);
95
- }
96
- );
97
- });
98
- fireEvent(wrapper.getByText('Hieu Pham'), 'press');
99
- expect(result).toMatchObject([
100
- { id: '3', name: 'Hieu Pham', target: 'give-shout-out' },
101
- ]);
102
- });
103
- });
104
- });
105
- });