@hero-design/rn-work-uikit 1.1.0-alpha.0 → 1.2.0-alpha.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/.cursorrules +57 -0
- package/CHANGELOG.md +8 -3
- package/DEVELOPMENT.md +118 -0
- package/THEME_OVERRIDE.md +52 -0
- package/eslint.config.js +20 -0
- package/lib/index.js +1000 -4
- package/locales/en_AU.js +10 -0
- package/locales/en_AU.mjs +8 -0
- package/locales/en_CA.js +10 -0
- package/locales/en_CA.mjs +8 -0
- package/locales/index.js +11 -0
- package/locales/index.mjs +9 -0
- package/locales/types.js +2 -0
- package/locales/types.mjs +1 -0
- package/package.json +8 -4
- package/rollup.config.mjs +18 -2
- package/src/__tests__/__snapshots__/index.spec.tsx.snap +91 -116
- package/src/__tests__/index.spec.tsx +15 -0
- package/src/__tests__/theme-export-override.spec.ts +96 -0
- package/src/components/TextInput/ErrorOrHelpText.tsx +58 -0
- package/src/components/TextInput/FloatingLabel.tsx +120 -0
- package/src/components/TextInput/InputComponent.tsx +61 -0
- package/src/components/TextInput/InputRow.tsx +103 -0
- package/src/components/TextInput/MaxLengthMessage.tsx +66 -0
- package/src/components/TextInput/PrefixComponent.tsx +77 -0
- package/src/components/TextInput/StyledTextInput.tsx +134 -0
- package/src/components/TextInput/SuffixComponent.tsx +73 -0
- package/src/components/TextInput/__tests__/ErrorOrHelpText.spec.tsx +20 -0
- package/src/components/TextInput/__tests__/FloatingLabel.spec.tsx +203 -0
- package/src/components/TextInput/__tests__/InputComponent.spec.tsx +39 -0
- package/src/components/TextInput/__tests__/InputRow.spec.tsx +275 -0
- package/src/components/TextInput/__tests__/MaxLengthMessage.spec.tsx +17 -0
- package/src/components/TextInput/__tests__/PrefixComponent.spec.tsx +14 -0
- package/src/components/TextInput/__tests__/StyledTextInput.spec.tsx +114 -0
- package/src/components/TextInput/__tests__/SuffixComponent.spec.tsx +20 -0
- package/src/components/TextInput/__tests__/__snapshots__/StyledTextInput.spec.tsx.snap +571 -0
- package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +5671 -0
- package/src/components/TextInput/__tests__/getState.spec.tsx +89 -0
- package/src/components/TextInput/__tests__/index.spec.tsx +699 -0
- package/src/components/TextInput/constants.ts +1 -0
- package/src/components/TextInput/index.tsx +327 -0
- package/src/components/TextInput/types.ts +95 -0
- package/src/emotion.d.ts +15 -0
- package/src/index.ts +16 -1
- package/src/jest.d.ts +24 -0
- package/src/theme/ThemeProvider.ts +20 -0
- package/src/theme/ThemeSwitcher.tsx +76 -0
- package/src/theme/__tests__/ThemeProvider.spec.tsx +32 -0
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +1851 -0
- package/src/theme/__tests__/index.spec.ts +7 -0
- package/src/theme/components/textInput.ts +92 -0
- package/src/theme/getTheme.ts +32 -0
- package/src/theme/index.ts +17 -0
- package/src/utils/__tests__/helpers.spec.ts +92 -0
- package/src/utils/helpers.ts +113 -0
- package/testUtils/renderWithTheme.tsx +6 -3
package/locales/en_AU.js
ADDED
package/locales/en_CA.js
ADDED
package/locales/index.js
ADDED
package/locales/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hero-design/rn-work-uikit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-alpha.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.js",
|
|
@@ -16,10 +16,14 @@
|
|
|
16
16
|
"build:types": "tsc --noEmit false --emitDeclarationOnly --project tsconfig.prod.json",
|
|
17
17
|
"build": "yarn build:js && yarn build:types",
|
|
18
18
|
"build:watch": "yarn build:js -w & yarn build:types -w",
|
|
19
|
-
"publish:npm": "yarn publish --access public"
|
|
19
|
+
"publish:npm": "yarn publish --access public",
|
|
20
|
+
"set-dev-env": "npm pkg set react-native=src/index.ts"
|
|
20
21
|
},
|
|
21
22
|
"dependencies": {
|
|
22
|
-
"@
|
|
23
|
+
"@emotion/native": "^11.9.3",
|
|
24
|
+
"@emotion/primitives-core": "11.0.0",
|
|
25
|
+
"@emotion/react": "^11.9.3",
|
|
26
|
+
"@hero-design/rn": "^8.101.1"
|
|
23
27
|
},
|
|
24
28
|
"peerDependencies": {
|
|
25
29
|
"@hero-design/react-native-month-year-picker": "^8.43.1",
|
|
@@ -45,7 +49,6 @@
|
|
|
45
49
|
"@babel/preset-react": "^7.26.3",
|
|
46
50
|
"@babel/preset-typescript": "^7.27.0",
|
|
47
51
|
"@babel/runtime": "^7.25.0",
|
|
48
|
-
"@emotion/jest": "^11.11.0",
|
|
49
52
|
"@eslint/compat": "^1.1.1",
|
|
50
53
|
"@eslint/eslintrc": "^3.1.0",
|
|
51
54
|
"@eslint/js": "^9.8.0",
|
|
@@ -107,6 +110,7 @@
|
|
|
107
110
|
"react-test-renderer": "18.2.0",
|
|
108
111
|
"rollup": "^4.24.3",
|
|
109
112
|
"rollup-plugin-copy": "^3.5.0",
|
|
113
|
+
"rollup-plugin-delete": "^3.0.1",
|
|
110
114
|
"rollup-plugin-flow": "^1.1.1",
|
|
111
115
|
"rollup-plugin-visualizer": "^5.12.0",
|
|
112
116
|
"ts-jest": "^29.1.1",
|
package/rollup.config.mjs
CHANGED
|
@@ -7,12 +7,15 @@ import replace from '@rollup/plugin-replace';
|
|
|
7
7
|
import flow from 'rollup-plugin-flow';
|
|
8
8
|
import { visualizer } from 'rollup-plugin-visualizer';
|
|
9
9
|
import pkg from './package.json' assert { type: 'json' };
|
|
10
|
+
import copy from 'rollup-plugin-copy';
|
|
11
|
+
import del from 'rollup-plugin-delete';
|
|
10
12
|
|
|
11
13
|
const extensions = ['.js', '.jsx', '.ts', '.tsx'];
|
|
12
14
|
|
|
13
15
|
const generateBuildStats = process.env.GENERATE_BUILD_STATS === 'true';
|
|
14
16
|
const bundleTemplate = process.env.BUNDLE_TEMPLATE || 'treemap';
|
|
15
|
-
const fileName =
|
|
17
|
+
const fileName =
|
|
18
|
+
process.env.FILE_NAME || `stats/${pkg.version}/rn-work-uikit-stats.html`;
|
|
16
19
|
|
|
17
20
|
export default [
|
|
18
21
|
{
|
|
@@ -63,6 +66,19 @@ export default [
|
|
|
63
66
|
}),
|
|
64
67
|
]
|
|
65
68
|
: []),
|
|
69
|
+
del({ targets: ['locales', 'types'] }),
|
|
70
|
+
copy({
|
|
71
|
+
targets: [
|
|
72
|
+
{
|
|
73
|
+
src: 'node_modules/@hero-design/rn/locales',
|
|
74
|
+
dest: '.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
src: 'node_modules/@hero-design/rn/types',
|
|
78
|
+
dest: '.',
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
}),
|
|
66
82
|
],
|
|
67
83
|
},
|
|
68
|
-
];
|
|
84
|
+
];
|
|
@@ -1,126 +1,120 @@
|
|
|
1
1
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
2
|
|
|
3
3
|
exports[`first test to ensure configure correctly should render TextInput with props in snapshot 1`] = `
|
|
4
|
-
<
|
|
5
|
-
|
|
4
|
+
<Pressable
|
|
5
|
+
accessibilityState={
|
|
6
6
|
{
|
|
7
|
-
"
|
|
7
|
+
"disabled": false,
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
+
disabled={false}
|
|
11
|
+
onPress={[Function]}
|
|
12
|
+
style={
|
|
13
|
+
[
|
|
14
|
+
[
|
|
15
|
+
{
|
|
16
|
+
"flexDirection": "row",
|
|
17
|
+
"marginTop": 7.846153846153847,
|
|
18
|
+
"minHeight": 54.92307692307692,
|
|
19
|
+
"paddingHorizontal": 15.692307692307693,
|
|
20
|
+
"width": "100%",
|
|
21
|
+
},
|
|
22
|
+
],
|
|
23
|
+
{},
|
|
24
|
+
]
|
|
25
|
+
}
|
|
26
|
+
testID="text-input"
|
|
10
27
|
>
|
|
11
28
|
<View
|
|
12
|
-
pointerEvents="
|
|
29
|
+
pointerEvents="none"
|
|
30
|
+
style={
|
|
31
|
+
[
|
|
32
|
+
[
|
|
33
|
+
{
|
|
34
|
+
"borderColor": "#e8e9ea",
|
|
35
|
+
"borderRadius": 8,
|
|
36
|
+
"borderWidth": 2,
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
[
|
|
40
|
+
{
|
|
41
|
+
"backgroundColor": "#ffffff",
|
|
42
|
+
},
|
|
43
|
+
{},
|
|
44
|
+
],
|
|
45
|
+
]
|
|
46
|
+
}
|
|
47
|
+
testID="text-input-border"
|
|
48
|
+
themeFocused={false}
|
|
49
|
+
themeState="filled"
|
|
50
|
+
/>
|
|
51
|
+
<View
|
|
13
52
|
style={
|
|
14
53
|
[
|
|
15
54
|
[
|
|
16
55
|
{
|
|
56
|
+
"backgroundColor": "transparent",
|
|
57
|
+
"borderRadius": 8,
|
|
58
|
+
"flex": 1,
|
|
59
|
+
"flexDirection": "column",
|
|
60
|
+
"marginBottom": 7.846153846153847,
|
|
17
61
|
"marginTop": 7.846153846153847,
|
|
18
|
-
"
|
|
62
|
+
"overflow": "hidden",
|
|
19
63
|
},
|
|
20
64
|
],
|
|
21
65
|
undefined,
|
|
22
66
|
]
|
|
23
67
|
}
|
|
24
|
-
testID="text-input"
|
|
25
68
|
>
|
|
26
69
|
<View
|
|
27
|
-
onLayout={[Function]}
|
|
28
70
|
style={
|
|
29
71
|
[
|
|
30
72
|
[
|
|
31
73
|
{
|
|
32
74
|
"alignItems": "center",
|
|
33
|
-
"backgroundColor": "#ffffff",
|
|
34
|
-
"borderRadius": 8,
|
|
35
75
|
"flexDirection": "row",
|
|
36
|
-
"
|
|
76
|
+
"flexGrow": 2,
|
|
77
|
+
"flexShrink": 1,
|
|
78
|
+
"gap": 3.9230769230769234,
|
|
37
79
|
},
|
|
38
80
|
],
|
|
39
81
|
undefined,
|
|
40
82
|
]
|
|
41
83
|
}
|
|
42
84
|
>
|
|
43
|
-
<View
|
|
44
|
-
style={
|
|
45
|
-
[
|
|
46
|
-
[
|
|
47
|
-
{
|
|
48
|
-
"borderColor": "#001f23",
|
|
49
|
-
"borderRadius": 8,
|
|
50
|
-
"borderWidth": 1,
|
|
51
|
-
},
|
|
52
|
-
],
|
|
53
|
-
[
|
|
54
|
-
{
|
|
55
|
-
"backgroundColor": "#ffffff",
|
|
56
|
-
},
|
|
57
|
-
undefined,
|
|
58
|
-
],
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
testID="text-input-border"
|
|
62
|
-
themeFocused={false}
|
|
63
|
-
themeState="filled"
|
|
64
|
-
/>
|
|
65
|
-
<View />
|
|
66
85
|
<AnimatedView
|
|
67
|
-
pointerEvents="none"
|
|
68
86
|
style={
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
],
|
|
81
|
-
[
|
|
82
|
-
{
|
|
83
|
-
"transformOrigin": "left top",
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
"transform": [
|
|
87
|
-
{
|
|
88
|
-
"translateY": {
|
|
89
|
-
"addListener": [MockFunction],
|
|
90
|
-
"removeListener": [MockFunction],
|
|
91
|
-
"setValue": [MockFunction],
|
|
92
|
-
},
|
|
93
|
-
},
|
|
94
|
-
{
|
|
95
|
-
"scale": {
|
|
96
|
-
"addListener": [MockFunction],
|
|
97
|
-
"removeListener": [MockFunction],
|
|
98
|
-
"setValue": [MockFunction],
|
|
99
|
-
},
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
},
|
|
103
|
-
],
|
|
104
|
-
]
|
|
87
|
+
{
|
|
88
|
+
"opacity": {
|
|
89
|
+
"_offset": 0,
|
|
90
|
+
"_value": 0,
|
|
91
|
+
"addListener": [MockFunction],
|
|
92
|
+
"interpolate": [MockFunction],
|
|
93
|
+
"removeAllListeners": [MockFunction],
|
|
94
|
+
"removeListener": [MockFunction],
|
|
95
|
+
"setValue": [MockFunction],
|
|
96
|
+
},
|
|
97
|
+
}
|
|
105
98
|
}
|
|
106
|
-
themeHasPrefix={false}
|
|
107
|
-
themeVariant="text"
|
|
108
99
|
/>
|
|
109
|
-
<
|
|
100
|
+
<AnimatedView
|
|
101
|
+
accessibilityElementsHidden={false}
|
|
102
|
+
accessibilityLabel="Text input field"
|
|
110
103
|
style={
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
104
|
+
{
|
|
105
|
+
"flex": 1,
|
|
106
|
+
"opacity": {
|
|
107
|
+
"_offset": 0,
|
|
108
|
+
"_value": 0,
|
|
109
|
+
"addListener": [MockFunction],
|
|
110
|
+
"interpolate": [MockFunction],
|
|
111
|
+
"removeAllListeners": [MockFunction],
|
|
112
|
+
"removeListener": [MockFunction],
|
|
113
|
+
"setValue": [MockFunction],
|
|
114
|
+
},
|
|
115
|
+
}
|
|
123
116
|
}
|
|
117
|
+
testID="input-row-input-wrapper"
|
|
124
118
|
>
|
|
125
119
|
<TextInput
|
|
126
120
|
accessibilityState={
|
|
@@ -139,13 +133,12 @@ exports[`first test to ensure configure correctly should render TextInput with p
|
|
|
139
133
|
[
|
|
140
134
|
[
|
|
141
135
|
{
|
|
142
|
-
"alignSelf": "stretch",
|
|
143
136
|
"flexGrow": 2,
|
|
144
137
|
"fontFamily": "BeVietnamPro-Regular",
|
|
145
138
|
"fontSize": 15.692307692307693,
|
|
146
139
|
"height": undefined,
|
|
147
|
-
"marginHorizontal": 7.846153846153847,
|
|
148
140
|
"maxHeight": 141.23076923076923,
|
|
141
|
+
"minHeight": 23.53846153846154,
|
|
149
142
|
"paddingVertical": 0,
|
|
150
143
|
"textAlignVertical": "center",
|
|
151
144
|
},
|
|
@@ -155,62 +148,44 @@ exports[`first test to ensure configure correctly should render TextInput with p
|
|
|
155
148
|
"backgroundColor": "#ffffff",
|
|
156
149
|
"color": "#001f23",
|
|
157
150
|
},
|
|
158
|
-
|
|
151
|
+
{},
|
|
159
152
|
],
|
|
160
153
|
]
|
|
161
154
|
}
|
|
162
|
-
testID="text-input
|
|
155
|
+
testID="text-input"
|
|
163
156
|
themeVariant="text"
|
|
164
157
|
value="test value"
|
|
165
158
|
/>
|
|
166
|
-
</
|
|
159
|
+
</AnimatedView>
|
|
167
160
|
</View>
|
|
168
161
|
<View
|
|
169
162
|
style={
|
|
170
163
|
[
|
|
171
164
|
[
|
|
172
165
|
{
|
|
173
|
-
"
|
|
174
|
-
"
|
|
175
|
-
"
|
|
166
|
+
"alignItems": "flex-start",
|
|
167
|
+
"flexDirection": "row",
|
|
168
|
+
"justifyContent": "space-between",
|
|
176
169
|
},
|
|
177
170
|
],
|
|
178
171
|
undefined,
|
|
179
172
|
]
|
|
180
173
|
}
|
|
181
|
-
|
|
182
|
-
<View
|
|
183
|
-
style={
|
|
184
|
-
[
|
|
185
|
-
[
|
|
186
|
-
{
|
|
187
|
-
"alignItems": "flex-start",
|
|
188
|
-
"flexDirection": "row",
|
|
189
|
-
"justifyContent": "space-between",
|
|
190
|
-
},
|
|
191
|
-
],
|
|
192
|
-
undefined,
|
|
193
|
-
]
|
|
194
|
-
}
|
|
195
|
-
/>
|
|
196
|
-
</View>
|
|
174
|
+
/>
|
|
197
175
|
</View>
|
|
198
176
|
<View
|
|
199
|
-
pointerEvents="box-none"
|
|
200
|
-
position="bottom"
|
|
201
177
|
style={
|
|
202
178
|
[
|
|
203
179
|
[
|
|
204
180
|
{
|
|
205
|
-
"
|
|
206
|
-
"flexDirection": "
|
|
207
|
-
"
|
|
208
|
-
"paddingVertical": 15.692307692307693,
|
|
181
|
+
"alignItems": "center",
|
|
182
|
+
"flexDirection": "row",
|
|
183
|
+
"justifyContent": "flex-end",
|
|
209
184
|
},
|
|
210
185
|
],
|
|
211
186
|
undefined,
|
|
212
187
|
]
|
|
213
188
|
}
|
|
214
189
|
/>
|
|
215
|
-
</
|
|
190
|
+
</Pressable>
|
|
216
191
|
`;
|
|
@@ -16,3 +16,18 @@ describe('first test to ensure configure correctly', () => {
|
|
|
16
16
|
expect(toJSON()).toMatchSnapshot();
|
|
17
17
|
});
|
|
18
18
|
});
|
|
19
|
+
|
|
20
|
+
describe('Export Completeness', () => {
|
|
21
|
+
it('should include all exports from @hero-design/rn', () => {
|
|
22
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
23
|
+
const baseRN = require('@hero-design/rn');
|
|
24
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
25
|
+
const workUIKit = require('../index');
|
|
26
|
+
|
|
27
|
+
const baseExports = Object.keys(baseRN);
|
|
28
|
+
|
|
29
|
+
baseExports.forEach((exportName) => {
|
|
30
|
+
expect(workUIKit).toHaveProperty(exportName);
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// Mock the entire theme module to avoid import resolution issues
|
|
2
|
+
jest.mock('../theme', () => {
|
|
3
|
+
const mockWorkTheme = {
|
|
4
|
+
colors: { text: 'work-color' },
|
|
5
|
+
fonts: { base: 'work-font' },
|
|
6
|
+
space: { base: 'work-space' },
|
|
7
|
+
__hd__: {
|
|
8
|
+
textInput: {
|
|
9
|
+
colors: {
|
|
10
|
+
text: '#WORK_THEME_COLOR',
|
|
11
|
+
background: '#WORK_BACKGROUND',
|
|
12
|
+
},
|
|
13
|
+
space: { containerPadding: 'WORK_PADDING' },
|
|
14
|
+
fonts: { text: 'WORK_FONT' },
|
|
15
|
+
},
|
|
16
|
+
button: { base: 'button' },
|
|
17
|
+
accordion: { base: 'accordion' },
|
|
18
|
+
},
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const mockGetTheme = jest.fn(() => mockWorkTheme);
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
__esModule: true,
|
|
25
|
+
default: mockWorkTheme,
|
|
26
|
+
getTheme: mockGetTheme,
|
|
27
|
+
Theme: {},
|
|
28
|
+
CustomTheme: {},
|
|
29
|
+
ThemeProvider: jest.fn(),
|
|
30
|
+
ThemeSwitcher: jest.fn(),
|
|
31
|
+
useTheme: jest.fn(),
|
|
32
|
+
withTheme: jest.fn(),
|
|
33
|
+
};
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// Mock the base @hero-design/rn
|
|
37
|
+
jest.mock('@hero-design/rn', () => ({
|
|
38
|
+
getTheme: jest.fn(() => ({
|
|
39
|
+
colors: { text: 'base-color' },
|
|
40
|
+
__hd__: {
|
|
41
|
+
textInput: {
|
|
42
|
+
colors: { text: 'BASE_THEME_COLOR' },
|
|
43
|
+
space: { containerPadding: 'BASE_PADDING' },
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
})),
|
|
47
|
+
// Mock styled function
|
|
48
|
+
styled: jest.fn(() => jest.fn(() => 'MockStyledComponent')),
|
|
49
|
+
// Mock Typography component
|
|
50
|
+
Typography: {
|
|
51
|
+
Caption: 'MockCaption',
|
|
52
|
+
},
|
|
53
|
+
// Re-export everything else as is
|
|
54
|
+
Button: 'MockButton',
|
|
55
|
+
TextInput: 'MockTextInput',
|
|
56
|
+
ThemeProvider: 'MockBaseThemeProvider',
|
|
57
|
+
useTheme: jest.fn(),
|
|
58
|
+
}));
|
|
59
|
+
|
|
60
|
+
describe('Theme Export Override', () => {
|
|
61
|
+
beforeEach(() => {
|
|
62
|
+
// Clear module cache to ensure fresh imports
|
|
63
|
+
jest.resetModules();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('should export work-specific theme with overridden textInput from index', () => {
|
|
67
|
+
// Re-import to get the mocked version
|
|
68
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
69
|
+
const { theme: workTheme } = require('../index');
|
|
70
|
+
|
|
71
|
+
// Verify that the theme has the work-specific textInput overrides
|
|
72
|
+
expect(workTheme.__hd__.textInput.colors.text).toBe('#WORK_THEME_COLOR');
|
|
73
|
+
expect(workTheme.__hd__.textInput.colors.background).toBe(
|
|
74
|
+
'#WORK_BACKGROUND'
|
|
75
|
+
);
|
|
76
|
+
expect(workTheme.__hd__.textInput.space.containerPadding).toBe(
|
|
77
|
+
'WORK_PADDING'
|
|
78
|
+
);
|
|
79
|
+
expect(workTheme.__hd__.textInput.fonts.text).toBe('WORK_FONT');
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should export work-specific getTheme function with overridden textInput', () => {
|
|
83
|
+
// Re-import to get the mocked version
|
|
84
|
+
// eslint-disable-next-line global-require, @typescript-eslint/no-var-requires
|
|
85
|
+
const { getTheme: workGetTheme } = require('../index');
|
|
86
|
+
|
|
87
|
+
const workTheme = workGetTheme();
|
|
88
|
+
|
|
89
|
+
// Verify that getTheme returns work-specific textInput theme
|
|
90
|
+
expect(workTheme.__hd__.textInput.colors.text).toBe('#WORK_THEME_COLOR');
|
|
91
|
+
expect(workTheme.__hd__.textInput.space.containerPadding).toBe(
|
|
92
|
+
'WORK_PADDING'
|
|
93
|
+
);
|
|
94
|
+
expect(workTheme.__hd__.textInput.fonts.text).toBe('WORK_FONT');
|
|
95
|
+
});
|
|
96
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Icon } from '@hero-design/rn';
|
|
3
|
+
import {
|
|
4
|
+
StyledErrorRow,
|
|
5
|
+
StyledError,
|
|
6
|
+
StyledHelperText,
|
|
7
|
+
} from './StyledTextInput';
|
|
8
|
+
|
|
9
|
+
export interface ErrorOrHelpTextProps {
|
|
10
|
+
/** Error message to display (takes priority) */
|
|
11
|
+
error?: string;
|
|
12
|
+
/** Helper text to display when no error */
|
|
13
|
+
helpText?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* ErrorOrHelpText Component
|
|
18
|
+
*
|
|
19
|
+
* Displays either error messages or help text below the TextInput.
|
|
20
|
+
* Shows error messages with a danger icon when present, otherwise displays help text.
|
|
21
|
+
*
|
|
22
|
+
* Key Features:
|
|
23
|
+
* - Conditional rendering: error takes priority over help text
|
|
24
|
+
* - Error messages include a danger icon for visual clarity
|
|
25
|
+
* - Uses styled components for consistent theming
|
|
26
|
+
* - Includes proper test IDs for testing
|
|
27
|
+
*
|
|
28
|
+
* Rendering Logic:
|
|
29
|
+
* 1. If error exists: Show error message with danger icon
|
|
30
|
+
* 2. If no error but helpText exists: Show help text
|
|
31
|
+
* 3. If neither exists: Render nothing
|
|
32
|
+
*
|
|
33
|
+
* @param props - The component props (see ErrorOrHelpTextProps interface for details)
|
|
34
|
+
*/
|
|
35
|
+
const ErrorOrHelpText: React.FC<ErrorOrHelpTextProps> = ({
|
|
36
|
+
error,
|
|
37
|
+
helpText,
|
|
38
|
+
}) => {
|
|
39
|
+
return error ? (
|
|
40
|
+
// Error state: Show error message with danger icon
|
|
41
|
+
<StyledErrorRow>
|
|
42
|
+
<Icon
|
|
43
|
+
testID="input-error-icon"
|
|
44
|
+
icon="circle-info"
|
|
45
|
+
size="xsmall"
|
|
46
|
+
intent="danger"
|
|
47
|
+
/>
|
|
48
|
+
<StyledError testID="input-error-message">{error}</StyledError>
|
|
49
|
+
</StyledErrorRow>
|
|
50
|
+
) : (
|
|
51
|
+
// Help text state: Show help text if provided
|
|
52
|
+
!!helpText && <StyledHelperText>{helpText}</StyledHelperText>
|
|
53
|
+
);
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
ErrorOrHelpText.displayName = 'ErrorOrHelpText';
|
|
57
|
+
|
|
58
|
+
export default React.memo(ErrorOrHelpText);
|