@hero-design/rn-work-uikit 1.9.5 → 1.10.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.
- package/CHANGELOG.md +21 -0
- package/README.md +219 -63
- package/assets/fonts/hero-icons-mobile.ttf +0 -0
- package/es/index.js +55337 -0
- package/lib/index.js +7173 -21259
- package/package.json +22 -22
- package/src/components/FormGroup/index.tsx +21 -10
- package/src/components/FormGroup/utils.ts +3 -3
- package/src/components/TextInput/InputRow.tsx +3 -6
- package/src/components/TextInput/index.tsx +4 -4
- package/src/components/TextInput/types.ts +4 -8
- package/types/index.d.ts +525 -0
- package/src/__tests__/index-export.spec.ts +0 -64
- package/src/__tests__/index.spec.tsx +0 -14
- package/src/components/DatePicker/__tests__/__snapshots__/index.spec.tsx.snap +0 -1649
- package/src/components/DatePicker/__tests__/index.spec.tsx +0 -56
- package/src/components/FormGroup/__tests__/__snapshots__/index.spec.tsx.snap +0 -908
- package/src/components/FormGroup/__tests__/index.spec.tsx +0 -319
- package/src/components/FormGroup/__tests__/utils.spec.ts +0 -73
- package/src/components/RichTextEditor/__tests__/EditorToolbar.spec.tsx +0 -154
- package/src/components/RichTextEditor/__tests__/MentionList.spec.tsx +0 -105
- package/src/components/RichTextEditor/__tests__/RichTextEditor.spec.tsx +0 -81
- package/src/components/RichTextEditor/__tests__/RichTextEditorInput.spec.tsx +0 -174
- package/src/components/RichTextEditor/__tests__/__snapshots__/EditorToolbar.spec.tsx.snap +0 -407
- package/src/components/RichTextEditor/__tests__/__snapshots__/MentionList.spec.tsx.snap +0 -13
- package/src/components/Select/__tests__/__snapshots__/index.spec.tsx.snap +0 -1324
- package/src/components/Select/__tests__/index.spec.tsx +0 -43
- package/src/components/TextInput/__tests__/ErrorOrHelpText.spec.tsx +0 -20
- package/src/components/TextInput/__tests__/FloatingLabel.spec.tsx +0 -190
- package/src/components/TextInput/__tests__/InputComponent.spec.tsx +0 -41
- package/src/components/TextInput/__tests__/InputRow.spec.tsx +0 -233
- package/src/components/TextInput/__tests__/MaxLengthMessage.spec.tsx +0 -17
- package/src/components/TextInput/__tests__/PrefixComponent.spec.tsx +0 -14
- package/src/components/TextInput/__tests__/StyledTextInput.spec.tsx +0 -114
- package/src/components/TextInput/__tests__/SuffixComponent.spec.tsx +0 -20
- package/src/components/TextInput/__tests__/__snapshots__/StyledTextInput.spec.tsx.snap +0 -583
- package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +0 -5835
- package/src/components/TextInput/__tests__/getState.spec.tsx +0 -89
- package/src/components/TextInput/__tests__/index.spec.tsx +0 -679
- package/src/components/TimePicker/__tests__/index.spec.tsx +0 -34
- package/src/theme/__tests__/ThemeProvider.spec.tsx +0 -32
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +0 -2042
- package/src/theme/__tests__/index.spec.ts +0 -7
- package/src/utils/__tests__/helpers.spec.ts +0 -92
- package/stats/1.3.0/rn-work-uikit-stats.html +0 -4842
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import Select from '..';
|
|
3
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
4
|
-
import { noop } from '../../../utils/functions';
|
|
5
|
-
|
|
6
|
-
const options = [
|
|
7
|
-
{ text: 'Monday', value: 'mon' },
|
|
8
|
-
{ text: 'Tuesday', value: 'tue' },
|
|
9
|
-
{ text: 'Wednesday', value: 'wed' },
|
|
10
|
-
{ text: 'Thursday', value: 'thu' },
|
|
11
|
-
{ text: 'Friday', value: 'fri' },
|
|
12
|
-
{ text: 'Saturday', value: 'sat' },
|
|
13
|
-
{ text: 'Sunday', value: 'sun', disabled: true },
|
|
14
|
-
];
|
|
15
|
-
|
|
16
|
-
describe('Select', () => {
|
|
17
|
-
it('renders correctly (snapshot)', () => {
|
|
18
|
-
const { toJSON } = renderWithTheme(
|
|
19
|
-
<Select
|
|
20
|
-
value="mon"
|
|
21
|
-
onConfirm={noop}
|
|
22
|
-
options={options}
|
|
23
|
-
label="Select Label"
|
|
24
|
-
/>
|
|
25
|
-
);
|
|
26
|
-
expect(toJSON()).toMatchSnapshot();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('MultiSelect', () => {
|
|
31
|
-
it('renders correctly (snapshot)', () => {
|
|
32
|
-
const { toJSON } = renderWithTheme(
|
|
33
|
-
<Select.Multi
|
|
34
|
-
value={['tue', 'wed']}
|
|
35
|
-
onConfirm={noop}
|
|
36
|
-
options={options}
|
|
37
|
-
label="Select Label"
|
|
38
|
-
footerLabel="Confirm"
|
|
39
|
-
/>
|
|
40
|
-
);
|
|
41
|
-
expect(toJSON()).toMatchSnapshot();
|
|
42
|
-
});
|
|
43
|
-
});
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
3
|
-
import ErrorOrHelpText from '../ErrorOrHelpText';
|
|
4
|
-
|
|
5
|
-
describe('ErrorOrHelpText', () => {
|
|
6
|
-
it('renders correctly with error', () => {
|
|
7
|
-
const { queryAllByText } = renderWithTheme(
|
|
8
|
-
<ErrorOrHelpText error="This is error" helpText="This is help text" />
|
|
9
|
-
);
|
|
10
|
-
expect(queryAllByText('This is error')).toHaveLength(1);
|
|
11
|
-
expect(queryAllByText('This is help text')).toHaveLength(0);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
it('renders correctly with help text', () => {
|
|
15
|
-
const { queryAllByText } = renderWithTheme(
|
|
16
|
-
<ErrorOrHelpText error="" helpText="This is help text" />
|
|
17
|
-
);
|
|
18
|
-
expect(queryAllByText('This is help text')).toHaveLength(1);
|
|
19
|
-
});
|
|
20
|
-
});
|
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
3
|
-
import FloatingLabel from '../FloatingLabel';
|
|
4
|
-
|
|
5
|
-
describe('FloatingLabel', () => {
|
|
6
|
-
describe('label text display based on required prop', () => {
|
|
7
|
-
it.each`
|
|
8
|
-
required | label | expectedText
|
|
9
|
-
${true} | ${'Email'} | ${'Email'}
|
|
10
|
-
${false} | ${'Phone'} | ${'Phone (Optional)'}
|
|
11
|
-
`(
|
|
12
|
-
'should display "$expectedText" with "$optionalText" when required is $required',
|
|
13
|
-
({ required, expectedText, label }) => {
|
|
14
|
-
const { getByTestId } = renderWithTheme(
|
|
15
|
-
<FloatingLabel
|
|
16
|
-
label={label}
|
|
17
|
-
variant="text"
|
|
18
|
-
state="default"
|
|
19
|
-
isFocused={false}
|
|
20
|
-
required={required}
|
|
21
|
-
isEmptyValue
|
|
22
|
-
/>
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
const labelComponent = getByTestId('input-label');
|
|
26
|
-
|
|
27
|
-
expect(labelComponent).toHaveTextContent(expectedText);
|
|
28
|
-
}
|
|
29
|
-
);
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
describe('label behavior based on focus and content state', () => {
|
|
33
|
-
it.each`
|
|
34
|
-
state | isEmptyValue | required | expectedText | description
|
|
35
|
-
${'focused'} | ${true} | ${true} | ${'Password'} | ${'user focuses empty input'}
|
|
36
|
-
${'filled'} | ${false} | ${true} | ${'Message'} | ${'user enters text in input'}
|
|
37
|
-
`(
|
|
38
|
-
'should show correct label when $description',
|
|
39
|
-
({ state, isEmptyValue, required, expectedText }) => {
|
|
40
|
-
const { getByTestId, queryByText } = renderWithTheme(
|
|
41
|
-
<FloatingLabel
|
|
42
|
-
label={expectedText}
|
|
43
|
-
variant="text"
|
|
44
|
-
state={state}
|
|
45
|
-
isFocused={state === 'focused'}
|
|
46
|
-
required={required}
|
|
47
|
-
isEmptyValue={isEmptyValue}
|
|
48
|
-
/>
|
|
49
|
-
);
|
|
50
|
-
|
|
51
|
-
// User should see the label behaving appropriately
|
|
52
|
-
const label = getByTestId('input-label');
|
|
53
|
-
expect(label).toHaveTextContent(expectedText);
|
|
54
|
-
|
|
55
|
-
const optionalLabel = queryByText(' (Optional)');
|
|
56
|
-
if (!required) {
|
|
57
|
-
expect(optionalLabel).not.toBeNull();
|
|
58
|
-
} else {
|
|
59
|
-
expect(optionalLabel).toBeNull();
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
);
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
describe('variant-specific positioning', () => {
|
|
66
|
-
it.each`
|
|
67
|
-
variant | required | expectedText | description
|
|
68
|
-
${'textarea'} | ${false} | ${'Description (Optional)'} | ${'multiline input with optional label'}
|
|
69
|
-
${'textarea'} | ${true} | ${'Description'} | ${'multiline input with required label'}
|
|
70
|
-
`(
|
|
71
|
-
'should position label appropriately for $variant ($description)',
|
|
72
|
-
({ variant, required, expectedText }) => {
|
|
73
|
-
const { getByTestId } = renderWithTheme(
|
|
74
|
-
<FloatingLabel
|
|
75
|
-
label="Description"
|
|
76
|
-
variant={variant}
|
|
77
|
-
state="default"
|
|
78
|
-
isFocused={false}
|
|
79
|
-
required={required}
|
|
80
|
-
isEmptyValue
|
|
81
|
-
/>
|
|
82
|
-
);
|
|
83
|
-
|
|
84
|
-
// User should see the label with proper variant positioning
|
|
85
|
-
const label = getByTestId('input-label');
|
|
86
|
-
expect(label).toHaveTextContent(expectedText);
|
|
87
|
-
}
|
|
88
|
-
);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
describe('when user encounters different input states', () => {
|
|
92
|
-
it.each`
|
|
93
|
-
state | required | expectedText | description
|
|
94
|
-
${'error'} | ${true} | ${'Email'} | ${'validation error with required field'}
|
|
95
|
-
${'disabled'} | ${false} | ${'Disabled Field (Optional)'} | ${'non-interactive optional field'}
|
|
96
|
-
`(
|
|
97
|
-
'should display appropriate styling for $state state ($description)',
|
|
98
|
-
({ state, required, expectedText }) => {
|
|
99
|
-
const { getByTestId } = renderWithTheme(
|
|
100
|
-
<FloatingLabel
|
|
101
|
-
label={state === 'error' ? 'Email' : 'Disabled Field'}
|
|
102
|
-
variant="text"
|
|
103
|
-
state={state}
|
|
104
|
-
isFocused={false}
|
|
105
|
-
required={required}
|
|
106
|
-
isEmptyValue
|
|
107
|
-
/>
|
|
108
|
-
);
|
|
109
|
-
|
|
110
|
-
// User should see the label with appropriate state styling
|
|
111
|
-
const label = getByTestId('input-label');
|
|
112
|
-
expect(label).toHaveTextContent(expectedText);
|
|
113
|
-
}
|
|
114
|
-
);
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
describe('when used with accessibility features', () => {
|
|
118
|
-
it('should provide proper accessibility labeling', () => {
|
|
119
|
-
const accessibilityId = 'email-input-label';
|
|
120
|
-
const { getByTestId } = renderWithTheme(
|
|
121
|
-
<FloatingLabel
|
|
122
|
-
label="Email Address"
|
|
123
|
-
variant="text"
|
|
124
|
-
state="default"
|
|
125
|
-
isFocused={false}
|
|
126
|
-
required
|
|
127
|
-
accessibilityLabelledBy={accessibilityId}
|
|
128
|
-
isEmptyValue
|
|
129
|
-
/>
|
|
130
|
-
);
|
|
131
|
-
|
|
132
|
-
// User should have proper accessibility support
|
|
133
|
-
const label = getByTestId('input-label-text');
|
|
134
|
-
expect(label).toHaveProp('nativeID', accessibilityId);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('label color styling based on state', () => {
|
|
139
|
-
it.each`
|
|
140
|
-
state | isFocused | expectedColor | description
|
|
141
|
-
${'default'} | ${false} | ${'#808f91'} | ${'inactive/empty field'}
|
|
142
|
-
${'default'} | ${true} | ${'#001f23'} | ${'user is typing'}
|
|
143
|
-
${'filled'} | ${false} | ${'#001f23'} | ${'field has content'}
|
|
144
|
-
${'filled'} | ${true} | ${'#001f23'} | ${'field has content and focused'}
|
|
145
|
-
${'error'} | ${false} | ${'#cb300a'} | ${'validation error'}
|
|
146
|
-
${'error'} | ${true} | ${'#001f23'} | ${'validation error but focused'}
|
|
147
|
-
${'disabled'} | ${false} | ${'#bfc1c5'} | ${'non-interactive field'}
|
|
148
|
-
${'readonly'} | ${false} | ${'#808f91'} | ${'read-only field'}
|
|
149
|
-
`(
|
|
150
|
-
'should apply $expectedColor color for $state state when focused=$isFocused ($description)',
|
|
151
|
-
({ state, isFocused, expectedColor: _expectedColor }) => {
|
|
152
|
-
const { getByTestId } = renderWithTheme(
|
|
153
|
-
<FloatingLabel
|
|
154
|
-
label={`${state} Label`}
|
|
155
|
-
variant="text"
|
|
156
|
-
state={state}
|
|
157
|
-
isFocused={isFocused}
|
|
158
|
-
required
|
|
159
|
-
isEmptyValue={state !== 'filled'}
|
|
160
|
-
/>
|
|
161
|
-
);
|
|
162
|
-
|
|
163
|
-
const label = getByTestId('input-label-text');
|
|
164
|
-
expect(label).toHaveProp('themeState', state);
|
|
165
|
-
}
|
|
166
|
-
);
|
|
167
|
-
|
|
168
|
-
describe('component behavior', () => {
|
|
169
|
-
it('should render correctly with all props', () => {
|
|
170
|
-
const { getByTestId } = renderWithTheme(
|
|
171
|
-
<FloatingLabel
|
|
172
|
-
label="Full Name"
|
|
173
|
-
variant="text"
|
|
174
|
-
state="filled"
|
|
175
|
-
isFocused
|
|
176
|
-
required={false}
|
|
177
|
-
accessibilityLabelledBy="fullname-label"
|
|
178
|
-
isEmptyValue={false}
|
|
179
|
-
/>
|
|
180
|
-
);
|
|
181
|
-
|
|
182
|
-
// User should see a fully rendered floating label
|
|
183
|
-
const label = getByTestId('input-label-text');
|
|
184
|
-
expect(label).toBeTruthy();
|
|
185
|
-
expect(label).toHaveProp('nativeID', 'fullname-label');
|
|
186
|
-
expect(label).toHaveTextContent('Full Name');
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
});
|
|
190
|
-
});
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { TextInput as RNTextInput } from 'react-native';
|
|
3
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
4
|
-
import InputComponent from '../InputComponent';
|
|
5
|
-
|
|
6
|
-
describe('InputComponent', () => {
|
|
7
|
-
it('renders correctly with renderInputValue', () => {
|
|
8
|
-
const ref = React.createRef<RNTextInput>();
|
|
9
|
-
const wrapper = renderWithTheme(
|
|
10
|
-
<InputComponent
|
|
11
|
-
variant="textarea"
|
|
12
|
-
nativeInputProps={{}}
|
|
13
|
-
renderInputValue={(props) => (
|
|
14
|
-
<RNTextInput
|
|
15
|
-
{...props}
|
|
16
|
-
value="customised text"
|
|
17
|
-
testID="custom-text-input"
|
|
18
|
-
/>
|
|
19
|
-
)}
|
|
20
|
-
ref={ref}
|
|
21
|
-
state="default"
|
|
22
|
-
/>
|
|
23
|
-
);
|
|
24
|
-
expect(wrapper.queryAllByTestId('custom-text-input')).toHaveLength(1);
|
|
25
|
-
expect(wrapper.queryAllByDisplayValue('customised text')).toHaveLength(1);
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('renders correctly without renderInputValue', () => {
|
|
29
|
-
const ref = React.createRef<RNTextInput>();
|
|
30
|
-
const wrapper = renderWithTheme(
|
|
31
|
-
<InputComponent
|
|
32
|
-
variant="textarea"
|
|
33
|
-
nativeInputProps={{ testID: 'text-input', value: 'text input value' }}
|
|
34
|
-
ref={ref}
|
|
35
|
-
state="default"
|
|
36
|
-
/>
|
|
37
|
-
);
|
|
38
|
-
expect(wrapper.queryAllByTestId('text-input')).toHaveLength(1);
|
|
39
|
-
expect(wrapper.queryAllByDisplayValue('text input value')).toHaveLength(1);
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import { Text } from 'react-native';
|
|
3
|
-
import type {
|
|
4
|
-
TextInputProps as NativeTextInputProps,
|
|
5
|
-
TextInput as RNTextInput,
|
|
6
|
-
} from 'react-native';
|
|
7
|
-
import { fireEvent, waitFor } from '@testing-library/react-native';
|
|
8
|
-
// import { TextInput as RNTextInput } from 'react-native';
|
|
9
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
10
|
-
import InputRow from '../InputRow';
|
|
11
|
-
|
|
12
|
-
describe('InputRow', () => {
|
|
13
|
-
const defaultProps = {
|
|
14
|
-
state: 'default' as const,
|
|
15
|
-
variant: 'text' as const,
|
|
16
|
-
testID: 'input-row',
|
|
17
|
-
nativeInputProps: {
|
|
18
|
-
value: '',
|
|
19
|
-
placeholder: 'Enter text',
|
|
20
|
-
testID: 'input-row-text-input',
|
|
21
|
-
},
|
|
22
|
-
isEmptyValue: true,
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
beforeEach(() => {
|
|
26
|
-
jest.clearAllMocks();
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe('visibility behavior', () => {
|
|
30
|
-
it('should be hidden when unfocused and empty by default', () => {
|
|
31
|
-
const { getByTestId } = renderWithTheme(<InputRow {...defaultProps} />);
|
|
32
|
-
expect(getByTestId('input-row')).toHaveProp('themeOpacity', 0);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it('should be visible when unfocused and empty if shouldShowWhenUnfocused is true', () => {
|
|
36
|
-
const { getByTestId } = renderWithTheme(
|
|
37
|
-
<InputRow {...defaultProps} shouldShowWhenUnfocused />
|
|
38
|
-
);
|
|
39
|
-
expect(getByTestId('input-row')).toHaveProp('themeOpacity', 1);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it('should become visible on focus', async () => {
|
|
43
|
-
const { getByTestId } = renderWithTheme(<InputRow {...defaultProps} />);
|
|
44
|
-
|
|
45
|
-
expect(getByTestId('input-row')).toHaveProp('themeOpacity', 0);
|
|
46
|
-
fireEvent(getByTestId('input-row-text-input'), 'focus');
|
|
47
|
-
|
|
48
|
-
await waitFor(() => {
|
|
49
|
-
expect(getByTestId('input-row')).toHaveProp('themeOpacity', 1);
|
|
50
|
-
});
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
it('should be visible when it has a value, even if unfocused', () => {
|
|
54
|
-
const { getByTestId } = renderWithTheme(
|
|
55
|
-
<InputRow
|
|
56
|
-
{...defaultProps}
|
|
57
|
-
isEmptyValue={false}
|
|
58
|
-
nativeInputProps={{
|
|
59
|
-
...defaultProps.nativeInputProps,
|
|
60
|
-
value: 'user@example.com',
|
|
61
|
-
}}
|
|
62
|
-
/>
|
|
63
|
-
);
|
|
64
|
-
expect(getByTestId('input-row')).toHaveProp('themeOpacity', 1);
|
|
65
|
-
});
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
describe('when user uses input with custom prefix', () => {
|
|
69
|
-
it('should render custom prefix element', () => {
|
|
70
|
-
const CustomPrefix = () => <Text testID="custom-prefix">Custom</Text>;
|
|
71
|
-
const ref = React.createRef<RNTextInput>();
|
|
72
|
-
|
|
73
|
-
const { getByTestId } = renderWithTheme(
|
|
74
|
-
<InputRow
|
|
75
|
-
{...defaultProps}
|
|
76
|
-
prefix={<CustomPrefix />}
|
|
77
|
-
isEmptyValue={false}
|
|
78
|
-
ref={ref}
|
|
79
|
-
shouldShowWhenUnfocused
|
|
80
|
-
/>
|
|
81
|
-
);
|
|
82
|
-
// User should see the custom prefix
|
|
83
|
-
expect(getByTestId('custom-prefix')).toBeTruthy();
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
describe('when user uses textarea variant', () => {
|
|
88
|
-
it('should render input component with textarea variant', () => {
|
|
89
|
-
const ref = React.createRef<RNTextInput>();
|
|
90
|
-
const { getByTestId } = renderWithTheme(
|
|
91
|
-
<InputRow
|
|
92
|
-
{...defaultProps}
|
|
93
|
-
variant="textarea"
|
|
94
|
-
isEmptyValue={false}
|
|
95
|
-
nativeInputProps={{
|
|
96
|
-
...defaultProps.nativeInputProps,
|
|
97
|
-
multiline: true,
|
|
98
|
-
numberOfLines: 4,
|
|
99
|
-
}}
|
|
100
|
-
ref={ref}
|
|
101
|
-
shouldShowWhenUnfocused
|
|
102
|
-
/>
|
|
103
|
-
);
|
|
104
|
-
// User should see the textarea input
|
|
105
|
-
const inputWrapper = getByTestId('input-row-input-wrapper');
|
|
106
|
-
expect(inputWrapper).toBeTruthy();
|
|
107
|
-
expect(inputWrapper).toHaveProp('accessibilityLabel', 'Text input field');
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
describe('when user encounters different input states', () => {
|
|
112
|
-
it('should render input wrapper in error state', () => {
|
|
113
|
-
const { getByTestId } = renderWithTheme(
|
|
114
|
-
<InputRow
|
|
115
|
-
{...defaultProps}
|
|
116
|
-
state="error"
|
|
117
|
-
isEmptyValue={false}
|
|
118
|
-
shouldShowWhenUnfocused
|
|
119
|
-
/>
|
|
120
|
-
);
|
|
121
|
-
// Components should render with error state
|
|
122
|
-
const inputWrapper = getByTestId('input-row-input-wrapper');
|
|
123
|
-
expect(inputWrapper).toBeTruthy();
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it('should handle disabled state appropriately', () => {
|
|
127
|
-
const { getByTestId } = renderWithTheme(
|
|
128
|
-
<InputRow
|
|
129
|
-
{...defaultProps}
|
|
130
|
-
state="disabled"
|
|
131
|
-
isEmptyValue
|
|
132
|
-
shouldShowWhenUnfocused
|
|
133
|
-
/>
|
|
134
|
-
);
|
|
135
|
-
// Even disabled inputs should render components
|
|
136
|
-
const inputWrapper = getByTestId('input-row-input-wrapper');
|
|
137
|
-
expect(inputWrapper).toBeTruthy();
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe('when user uses custom input renderer', () => {
|
|
142
|
-
it('should use custom render function for input value', () => {
|
|
143
|
-
const customRenderer = (inputProps: NativeTextInputProps) => (
|
|
144
|
-
<Text testID="custom-input-renderer">Custom: {inputProps.value}</Text>
|
|
145
|
-
);
|
|
146
|
-
const ref = React.createRef<RNTextInput>();
|
|
147
|
-
|
|
148
|
-
const { getByTestId } = renderWithTheme(
|
|
149
|
-
<InputRow
|
|
150
|
-
{...defaultProps}
|
|
151
|
-
renderInputValue={customRenderer}
|
|
152
|
-
isEmptyValue={false}
|
|
153
|
-
nativeInputProps={{
|
|
154
|
-
...defaultProps.nativeInputProps,
|
|
155
|
-
value: 'test value',
|
|
156
|
-
}}
|
|
157
|
-
ref={ref}
|
|
158
|
-
shouldShowWhenUnfocused
|
|
159
|
-
/>
|
|
160
|
-
);
|
|
161
|
-
// User should see the custom rendered input
|
|
162
|
-
expect(getByTestId('custom-input-renderer')).toBeTruthy();
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
describe('input reference handling', () => {
|
|
167
|
-
it('should properly handle input ref', () => {
|
|
168
|
-
const ref = React.createRef<RNTextInput>();
|
|
169
|
-
renderWithTheme(
|
|
170
|
-
<InputRow
|
|
171
|
-
{...defaultProps}
|
|
172
|
-
isEmptyValue={false}
|
|
173
|
-
ref={ref}
|
|
174
|
-
shouldShowWhenUnfocused
|
|
175
|
-
/>
|
|
176
|
-
);
|
|
177
|
-
expect(ref.current).toBeDefined();
|
|
178
|
-
});
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
describe('accessibility features', () => {
|
|
182
|
-
it('should provide proper accessibility labels for input wrapper', () => {
|
|
183
|
-
const ref = React.createRef<RNTextInput>();
|
|
184
|
-
const { getByTestId } = renderWithTheme(
|
|
185
|
-
<InputRow
|
|
186
|
-
{...defaultProps}
|
|
187
|
-
isEmptyValue={false}
|
|
188
|
-
ref={ref}
|
|
189
|
-
shouldShowWhenUnfocused
|
|
190
|
-
/>
|
|
191
|
-
);
|
|
192
|
-
// User should have proper accessibility support
|
|
193
|
-
const inputWrapper = getByTestId('input-row-input-wrapper');
|
|
194
|
-
expect(inputWrapper).toHaveProp('accessibilityLabel', 'Text input field');
|
|
195
|
-
});
|
|
196
|
-
});
|
|
197
|
-
|
|
198
|
-
describe('component behavior', () => {
|
|
199
|
-
it('should render correctly with all props', () => {
|
|
200
|
-
const ref = React.createRef<RNTextInput>();
|
|
201
|
-
const { getByTestId } = renderWithTheme(
|
|
202
|
-
<InputRow
|
|
203
|
-
{...defaultProps}
|
|
204
|
-
prefix="search"
|
|
205
|
-
isEmptyValue={false}
|
|
206
|
-
nativeInputProps={{
|
|
207
|
-
...defaultProps.nativeInputProps,
|
|
208
|
-
value: 'test@example.com',
|
|
209
|
-
placeholder: 'Enter email',
|
|
210
|
-
}}
|
|
211
|
-
ref={ref}
|
|
212
|
-
shouldShowWhenUnfocused
|
|
213
|
-
/>
|
|
214
|
-
);
|
|
215
|
-
const inputWrapper = getByTestId('input-row-input-wrapper');
|
|
216
|
-
expect(inputWrapper).toBeTruthy();
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it('should render without prefix', () => {
|
|
220
|
-
const ref = React.createRef<RNTextInput>();
|
|
221
|
-
const { getByTestId } = renderWithTheme(
|
|
222
|
-
<InputRow
|
|
223
|
-
{...defaultProps}
|
|
224
|
-
isEmptyValue={false}
|
|
225
|
-
ref={ref}
|
|
226
|
-
shouldShowWhenUnfocused
|
|
227
|
-
/>
|
|
228
|
-
);
|
|
229
|
-
const inputWrapper = getByTestId('input-row-input-wrapper');
|
|
230
|
-
expect(inputWrapper).toBeTruthy();
|
|
231
|
-
});
|
|
232
|
-
});
|
|
233
|
-
});
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
3
|
-
import MaxLengthMessage from '../MaxLengthMessage';
|
|
4
|
-
|
|
5
|
-
describe('MaxLengthMessage', () => {
|
|
6
|
-
it('renders correctly with maxLength', () => {
|
|
7
|
-
const { queryAllByText } = renderWithTheme(
|
|
8
|
-
<MaxLengthMessage
|
|
9
|
-
maxLength={10}
|
|
10
|
-
state="default"
|
|
11
|
-
currentLength={5}
|
|
12
|
-
hideCharacterCount={false}
|
|
13
|
-
/>
|
|
14
|
-
);
|
|
15
|
-
expect(queryAllByText('5/10')).toHaveLength(1);
|
|
16
|
-
});
|
|
17
|
-
});
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
3
|
-
import PrefixComponent from '../PrefixComponent';
|
|
4
|
-
|
|
5
|
-
describe('PrefixComponent', () => {
|
|
6
|
-
it('renders prefix icon', () => {
|
|
7
|
-
const wrapper = renderWithTheme(
|
|
8
|
-
<PrefixComponent prefix="dollar-sign" state="default" />
|
|
9
|
-
);
|
|
10
|
-
expect(wrapper.getByLabelText('Prefix icon: dollar-sign')).toBeDefined();
|
|
11
|
-
// Optionally, keep testID fallback
|
|
12
|
-
expect(wrapper.getByTestId('input-prefix')).toBeDefined();
|
|
13
|
-
});
|
|
14
|
-
});
|
|
@@ -1,114 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import renderWithTheme from '../../../../testUtils/renderWithTheme';
|
|
3
|
-
import {
|
|
4
|
-
StyledHelperText,
|
|
5
|
-
StyledTextInput,
|
|
6
|
-
StyledCharacterCount,
|
|
7
|
-
StyledError,
|
|
8
|
-
StyledErrorRow,
|
|
9
|
-
StyledLabel,
|
|
10
|
-
StyledBorder,
|
|
11
|
-
} from '../StyledTextInput';
|
|
12
|
-
|
|
13
|
-
describe('StyledLabel', () => {
|
|
14
|
-
it.each`
|
|
15
|
-
themeState
|
|
16
|
-
${'default'}
|
|
17
|
-
${'filled'}
|
|
18
|
-
${'error'}
|
|
19
|
-
${'disabled'}
|
|
20
|
-
${'readonly'}
|
|
21
|
-
`('renders correctly with themeState $themeState', ({ themeState }): void => {
|
|
22
|
-
const { toJSON } = renderWithTheme(
|
|
23
|
-
<StyledLabel themeState={themeState}>Label</StyledLabel>
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
expect(toJSON()).toMatchSnapshot();
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
describe('StyledErrorRow', () => {
|
|
31
|
-
it('renders correctly', (): void => {
|
|
32
|
-
const { toJSON } = renderWithTheme(<StyledErrorRow />);
|
|
33
|
-
|
|
34
|
-
expect(toJSON()).toMatchSnapshot();
|
|
35
|
-
});
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
describe('StyledError', () => {
|
|
39
|
-
it('renders correctly', (): void => {
|
|
40
|
-
const { toJSON } = renderWithTheme(
|
|
41
|
-
<StyledError>must not exceed character limit</StyledError>
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
expect(toJSON()).toMatchSnapshot();
|
|
45
|
-
});
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
describe('StyledCharacterCount', () => {
|
|
49
|
-
it.each`
|
|
50
|
-
themeState
|
|
51
|
-
${'default'}
|
|
52
|
-
${'filled'}
|
|
53
|
-
${'error'}
|
|
54
|
-
${'disabled'}
|
|
55
|
-
${'readonly'}
|
|
56
|
-
`('renders correctly with themeState $themeState', ({ themeState }): void => {
|
|
57
|
-
const { toJSON } = renderWithTheme(
|
|
58
|
-
<StyledCharacterCount themeState={themeState}>
|
|
59
|
-
100/255
|
|
60
|
-
</StyledCharacterCount>
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
expect(toJSON()).toMatchSnapshot();
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe('StyledHelperText', () => {
|
|
68
|
-
it('renders correctly', (): void => {
|
|
69
|
-
const { toJSON } = renderWithTheme(
|
|
70
|
-
<StyledHelperText>helper text</StyledHelperText>
|
|
71
|
-
);
|
|
72
|
-
|
|
73
|
-
expect(toJSON()).toMatchSnapshot();
|
|
74
|
-
});
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
describe('StyledBorder', () => {
|
|
78
|
-
it.each`
|
|
79
|
-
themeState
|
|
80
|
-
${'default'}
|
|
81
|
-
${'filled'}
|
|
82
|
-
${'error'}
|
|
83
|
-
${'disabled'}
|
|
84
|
-
${'readonly'}
|
|
85
|
-
`('renders correctly with themeState $themeState', ({ themeState }): void => {
|
|
86
|
-
const { toJSON } = renderWithTheme(
|
|
87
|
-
<StyledBorder themeState={themeState} themeFocused={false} />
|
|
88
|
-
);
|
|
89
|
-
|
|
90
|
-
expect(toJSON()).toMatchSnapshot();
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('renders correctly when focused', (): void => {
|
|
94
|
-
const { toJSON } = renderWithTheme(
|
|
95
|
-
<StyledBorder themeState="error" themeFocused />
|
|
96
|
-
);
|
|
97
|
-
|
|
98
|
-
expect(toJSON()).toMatchSnapshot();
|
|
99
|
-
});
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
describe('StyledTextInput', () => {
|
|
103
|
-
it.each`
|
|
104
|
-
themeVariant
|
|
105
|
-
${'text'}
|
|
106
|
-
${'textarea'}
|
|
107
|
-
`('renders correctly with $themeState state', ({ themeVariant }) => {
|
|
108
|
-
const { toJSON } = renderWithTheme(
|
|
109
|
-
<StyledTextInput themeVariant={themeVariant} />
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
expect(toJSON()).toMatchSnapshot();
|
|
113
|
-
});
|
|
114
|
-
});
|