@hero-design/rn 8.104.1-alpha.2 → 8.105.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 (77) hide show
  1. package/.turbo/turbo-build.log +3 -3
  2. package/CHANGELOG.md +6 -10
  3. package/assets/fonts/hero-icons-mobile.ttf +0 -0
  4. package/es/index.js +683 -402
  5. package/lib/assets/fonts/hero-icons-mobile.ttf +0 -0
  6. package/lib/index.js +683 -401
  7. package/package.json +1 -1
  8. package/src/components/Calendar/CalendarRange.tsx +35 -117
  9. package/src/components/Calendar/__tests__/helper.spec.ts +197 -0
  10. package/src/components/Calendar/constants.ts +9 -0
  11. package/src/components/Calendar/helpers.ts +112 -0
  12. package/src/components/Calendar/index.tsx +34 -159
  13. package/src/components/Calendar/shared/hooks/useCalendarLayout.ts +37 -0
  14. package/src/components/Calendar/types.ts +62 -0
  15. package/src/components/DatePicker/DatePickerCalendar.tsx +2 -1
  16. package/src/components/Icon/HeroIcon/glyphMap.json +1 -1
  17. package/src/components/Icon/IconList.ts +2 -0
  18. package/src/components/SegmentedControl/SegmentedItem.tsx +192 -0
  19. package/src/components/SegmentedControl/StyledSegmentedControl.tsx +62 -0
  20. package/src/components/SegmentedControl/__tests__/SegmentedItem.spec.tsx +162 -0
  21. package/src/components/SegmentedControl/__tests__/__snapshots__/SegmentedItem.spec.tsx.snap +131 -0
  22. package/src/components/SegmentedControl/__tests__/__snapshots__/index.spec.tsx.snap +359 -0
  23. package/src/components/SegmentedControl/__tests__/index.spec.tsx +247 -0
  24. package/src/components/SegmentedControl/index.tsx +61 -0
  25. package/src/components/SegmentedControl/types.ts +46 -0
  26. package/src/components/Typography/Body/StyledBody.tsx +2 -2
  27. package/src/components/Typography/Body/__tests__/__snapshots__/index.spec.tsx.snap +51 -0
  28. package/src/components/Typography/Body/__tests__/index.spec.tsx +1 -0
  29. package/src/components/Typography/Body/index.tsx +2 -13
  30. package/src/components/Typography/Caption/StyledCaption.tsx +2 -2
  31. package/src/components/Typography/Caption/__tests__/__snapshots__/index.spec.tsx.snap +50 -0
  32. package/src/components/Typography/Caption/__tests__/index.spec.tsx +1 -0
  33. package/src/components/Typography/Caption/index.tsx +2 -13
  34. package/src/components/Typography/Label/StyledLabel.tsx +2 -2
  35. package/src/components/Typography/Label/__tests__/__snapshots__/index.spec.tsx.snap +48 -0
  36. package/src/components/Typography/Label/__tests__/index.spec.tsx +1 -0
  37. package/src/components/Typography/Label/index.tsx +2 -13
  38. package/src/components/Typography/Title/StyledTitle.tsx +2 -2
  39. package/src/components/Typography/Title/__tests__/__snapshots__/index.spec.tsx.snap +51 -0
  40. package/src/components/Typography/Title/__tests__/index.spec.tsx +1 -0
  41. package/src/components/Typography/Title/index.tsx +2 -13
  42. package/src/components/Typography/types.ts +3 -2
  43. package/src/index.ts +2 -0
  44. package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +54 -0
  45. package/src/theme/components/segmentedControl.ts +60 -0
  46. package/src/theme/components/typography.ts +1 -0
  47. package/src/theme/getTheme.ts +3 -0
  48. package/src/types.ts +2 -0
  49. package/stats/8.104.0/rn-stats.html +3 -1
  50. package/stats/8.105.0/rn-stats.html +4844 -0
  51. package/types/components/Calendar/CalendarRange.d.ts +4 -16
  52. package/types/components/Calendar/constants.d.ts +4 -0
  53. package/types/components/Calendar/helpers.d.ts +14 -0
  54. package/types/components/Calendar/index.d.ts +5 -56
  55. package/types/components/Calendar/shared/hooks/useCalendarLayout.d.ts +8 -0
  56. package/types/components/Calendar/types.d.ts +58 -0
  57. package/types/components/Icon/IconList.d.ts +1 -1
  58. package/types/components/Icon/index.d.ts +1 -1
  59. package/types/components/SegmentedControl/SegmentedItem.d.ts +18 -0
  60. package/types/components/SegmentedControl/StyledSegmentedControl.d.ts +26 -0
  61. package/types/components/SegmentedControl/index.d.ts +31 -0
  62. package/types/components/SegmentedControl/types.d.ts +43 -0
  63. package/types/components/TextInput/index.d.ts +1 -1
  64. package/types/components/Typography/Body/StyledBody.d.ts +2 -2
  65. package/types/components/Typography/Body/index.d.ts +2 -1
  66. package/types/components/Typography/Caption/StyledCaption.d.ts +2 -2
  67. package/types/components/Typography/Caption/index.d.ts +2 -1
  68. package/types/components/Typography/Label/StyledLabel.d.ts +2 -2
  69. package/types/components/Typography/Label/index.d.ts +2 -1
  70. package/types/components/Typography/Title/StyledTitle.d.ts +2 -2
  71. package/types/components/Typography/Title/index.d.ts +2 -1
  72. package/types/components/Typography/types.d.ts +1 -1
  73. package/types/index.d.ts +2 -1
  74. package/types/theme/components/segmentedControl.d.ts +46 -0
  75. package/types/theme/components/typography.d.ts +1 -0
  76. package/types/theme/getTheme.d.ts +2 -0
  77. package/types/types.d.ts +2 -1
@@ -0,0 +1,162 @@
1
+ import React from 'react';
2
+ import { fireEvent } from '@testing-library/react-native';
3
+ import SegmentedItem from '../SegmentedItem';
4
+ import type { SegmentedItemProps } from '../SegmentedItem';
5
+ import renderWithTheme from '../../../testHelpers/renderWithTheme';
6
+ import { scale } from '../../../utils/scale';
7
+
8
+ describe('SegmentedItem', () => {
9
+ const defaultProps: SegmentedItemProps = {
10
+ value: 'test-item',
11
+ label: 'Test Item',
12
+ onPress: jest.fn(),
13
+ };
14
+
15
+ beforeEach(() => {
16
+ jest.clearAllMocks();
17
+ });
18
+
19
+ it('should render correctly with default props', () => {
20
+ const { toJSON, getByText } = renderWithTheme(
21
+ <SegmentedItem {...defaultProps} />
22
+ );
23
+
24
+ expect(getByText('Test Item')).toBeVisible();
25
+ expect(toJSON()).toMatchSnapshot();
26
+ });
27
+
28
+ describe('sizing', () => {
29
+ it.each`
30
+ size | expectedHeight
31
+ ${'medium'} | ${scale(28)}
32
+ ${'large'} | ${scale(36)}
33
+ `(
34
+ 'should have correct height of $expectedHeight for $size size',
35
+ ({ size, expectedHeight }) => {
36
+ const { getByTestId } = renderWithTheme(
37
+ <SegmentedItem
38
+ {...defaultProps}
39
+ size={size}
40
+ testID="segmented-item"
41
+ />
42
+ );
43
+
44
+ const item = getByTestId('segmented-item');
45
+ expect(item).toHaveStyle({ height: expectedHeight });
46
+ }
47
+ );
48
+ });
49
+
50
+ it('should not call onPress when disabled', () => {
51
+ const onPress = jest.fn();
52
+ const { getByText } = renderWithTheme(
53
+ <SegmentedItem {...defaultProps} onPress={onPress} disabled />
54
+ );
55
+
56
+ fireEvent.press(getByText('Test Item'));
57
+ expect(onPress).not.toHaveBeenCalled();
58
+ });
59
+
60
+ it('should display icons when provided', () => {
61
+ const { getByTestId } = renderWithTheme(
62
+ <SegmentedItem
63
+ {...defaultProps}
64
+ prefix="home-outlined"
65
+ suffix="cog-outlined"
66
+ testID="item-with-icons"
67
+ />
68
+ );
69
+
70
+ expect(getByTestId('item-with-icons-suffix')).toBeVisible();
71
+ expect(getByTestId('item-with-icons-prefix')).toBeVisible();
72
+ expect(getByTestId('item-with-icons')).toBeVisible();
73
+ });
74
+
75
+ it.each`
76
+ value | max | expectedText
77
+ ${10} | ${10} | ${'10'}
78
+ ${15} | ${10} | ${'10+'}
79
+ ${99} | ${undefined} | ${'99'}
80
+ `(
81
+ 'should display count badge $expectedText for $value and $max',
82
+ ({ value, max, expectedText }) => {
83
+ const { getByText } = renderWithTheme(
84
+ <SegmentedItem
85
+ {...defaultProps}
86
+ badge={{ type: 'counter', value, max }}
87
+ />
88
+ );
89
+
90
+ expect(getByText('Test Item')).toBeVisible();
91
+ expect(getByText(expectedText)).toBeVisible();
92
+ }
93
+ );
94
+
95
+ it('should display status badge correctly', () => {
96
+ const { getByText, getByTestId } = renderWithTheme(
97
+ <SegmentedItem
98
+ {...defaultProps}
99
+ badge={{ type: 'status' }}
100
+ testID="item-with-status-badge"
101
+ />
102
+ );
103
+
104
+ expect(getByText('Test Item')).toBeVisible();
105
+ expect(getByTestId('item-with-status-badge-badge')).toBeVisible();
106
+ });
107
+
108
+ it('should display subtext when provided', () => {
109
+ const { getByText } = renderWithTheme(
110
+ <SegmentedItem {...defaultProps} subText="Secondary info" />
111
+ );
112
+
113
+ expect(getByText('Test Item')).toBeVisible();
114
+ expect(getByText('Secondary info')).toBeVisible();
115
+ expect(getByText('·')).toBeVisible(); // bullet separator
116
+ });
117
+
118
+ it('should render complex item with all features correctly', () => {
119
+ const { getByText, getByTestId } = renderWithTheme(
120
+ <SegmentedItem
121
+ value="complex-item"
122
+ label="Dashboard"
123
+ subText="Overview"
124
+ prefix="home-outlined"
125
+ suffix="cog-outlined"
126
+ badge={{ type: 'counter', value: 5, max: 3 }}
127
+ selected
128
+ size="large"
129
+ testID="complex-item"
130
+ onPress={jest.fn()}
131
+ />
132
+ );
133
+
134
+ // Label and subtext
135
+ expect(getByText('Dashboard')).toBeVisible();
136
+ expect(getByText('Overview')).toBeVisible();
137
+ expect(getByText('·')).toBeVisible(); // bullet separator
138
+
139
+ // Icons
140
+ expect(getByTestId('complex-item-prefix')).toBeVisible();
141
+ expect(getByTestId('complex-item-suffix')).toBeVisible();
142
+
143
+ // Badge (over max)
144
+ expect(getByText('3+')).toBeVisible();
145
+
146
+ // Main item
147
+ expect(getByTestId('complex-item')).toBeVisible();
148
+ expect(getByTestId('complex-item')).toHaveStyle({
149
+ height: scale(36),
150
+ }); // large size
151
+ });
152
+
153
+ it('should call onPress when pressed', () => {
154
+ const onPress = jest.fn();
155
+ const { getByText } = renderWithTheme(
156
+ <SegmentedItem {...defaultProps} onPress={onPress} />
157
+ );
158
+
159
+ fireEvent.press(getByText('Test Item'));
160
+ expect(onPress).toHaveBeenCalledTimes(1);
161
+ });
162
+ });
@@ -0,0 +1,131 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`SegmentedItem should render correctly with default props 1`] = `
4
+ <View
5
+ style={
6
+ {
7
+ "flex": 1,
8
+ }
9
+ }
10
+ >
11
+ <View
12
+ accessibilityState={
13
+ {
14
+ "busy": undefined,
15
+ "checked": undefined,
16
+ "disabled": undefined,
17
+ "expanded": undefined,
18
+ "selected": undefined,
19
+ }
20
+ }
21
+ accessibilityValue={
22
+ {
23
+ "max": undefined,
24
+ "min": undefined,
25
+ "now": undefined,
26
+ "text": undefined,
27
+ }
28
+ }
29
+ accessible={true}
30
+ collapsable={false}
31
+ focusable={true}
32
+ onClick={[Function]}
33
+ onResponderGrant={[Function]}
34
+ onResponderMove={[Function]}
35
+ onResponderRelease={[Function]}
36
+ onResponderTerminate={[Function]}
37
+ onResponderTerminationRequest={[Function]}
38
+ onStartShouldSetResponder={[Function]}
39
+ style={
40
+ {
41
+ "alignItems": "center",
42
+ "backgroundColor": "transparent",
43
+ "borderRadius": 12,
44
+ "flexDirection": "row",
45
+ "flexGrow": 1,
46
+ "height": 28,
47
+ "justifyContent": "center",
48
+ "opacity": 1,
49
+ }
50
+ }
51
+ >
52
+ <View
53
+ style={
54
+ [
55
+ {},
56
+ [
57
+ {
58
+ "alignItems": "center",
59
+ "flexDirection": "row",
60
+ "gap": 8,
61
+ "justifyContent": "center",
62
+ },
63
+ undefined,
64
+ ],
65
+ ]
66
+ }
67
+ >
68
+ <View
69
+ style={
70
+ [
71
+ {},
72
+ [
73
+ {
74
+ "alignItems": "center",
75
+ "flexDirection": "row",
76
+ "gap": 4,
77
+ "justifyContent": "center",
78
+ },
79
+ undefined,
80
+ ],
81
+ ]
82
+ }
83
+ >
84
+ <Text
85
+ allowFontScaling={false}
86
+ style={
87
+ [
88
+ {
89
+ "color": "#808f91",
90
+ "fontFamily": "BeVietnamPro-SemiBold",
91
+ "fontSize": 14,
92
+ "letterSpacing": 0.24,
93
+ "lineHeight": 22,
94
+ },
95
+ [
96
+ {},
97
+ undefined,
98
+ ],
99
+ ]
100
+ }
101
+ themeIntent="inactive"
102
+ themeTypeface="neutral"
103
+ themeVariant="small-bold"
104
+ >
105
+ Test Item
106
+ </Text>
107
+ </View>
108
+ </View>
109
+ </View>
110
+ <View
111
+ pointerEvents="box-none"
112
+ position="bottom"
113
+ style={
114
+ [
115
+ {
116
+ "bottom": 0,
117
+ "elevation": 9999,
118
+ "flexDirection": "column-reverse",
119
+ "left": 0,
120
+ "paddingHorizontal": 24,
121
+ "paddingVertical": 16,
122
+ "position": "absolute",
123
+ "right": 0,
124
+ "top": 0,
125
+ },
126
+ undefined,
127
+ ]
128
+ }
129
+ />
130
+ </View>
131
+ `;
@@ -0,0 +1,359 @@
1
+ // Jest Snapshot v1, https://goo.gl/fbAQLP
2
+
3
+ exports[`SegmentedControl should render correctly with default props 1`] = `
4
+ <View
5
+ style={
6
+ {
7
+ "flex": 1,
8
+ }
9
+ }
10
+ >
11
+ <View
12
+ style={
13
+ [
14
+ {},
15
+ [
16
+ {
17
+ "alignItems": "center",
18
+ "alignSelf": "flex-start",
19
+ "backgroundColor": "#f6f6f7",
20
+ "borderRadius": 16,
21
+ "flexDirection": "row",
22
+ "height": 36,
23
+ "justifyContent": "center",
24
+ "paddingHorizontal": 4,
25
+ },
26
+ undefined,
27
+ ],
28
+ ]
29
+ }
30
+ themeSize="medium"
31
+ >
32
+ <View
33
+ accessibilityState={
34
+ {
35
+ "busy": undefined,
36
+ "checked": undefined,
37
+ "disabled": undefined,
38
+ "expanded": undefined,
39
+ "selected": undefined,
40
+ }
41
+ }
42
+ accessibilityValue={
43
+ {
44
+ "max": undefined,
45
+ "min": undefined,
46
+ "now": undefined,
47
+ "text": undefined,
48
+ }
49
+ }
50
+ accessible={true}
51
+ collapsable={false}
52
+ focusable={true}
53
+ onClick={[Function]}
54
+ onResponderGrant={[Function]}
55
+ onResponderMove={[Function]}
56
+ onResponderRelease={[Function]}
57
+ onResponderTerminate={[Function]}
58
+ onResponderTerminationRequest={[Function]}
59
+ onStartShouldSetResponder={[Function]}
60
+ style={
61
+ {
62
+ "alignItems": "center",
63
+ "backgroundColor": "#ffffff",
64
+ "borderRadius": 12,
65
+ "elevation": 6,
66
+ "flexDirection": "row",
67
+ "flexGrow": 1,
68
+ "height": 28,
69
+ "justifyContent": "center",
70
+ "opacity": 1,
71
+ "shadowColor": "#001f23",
72
+ "shadowOffset": {
73
+ "height": 2,
74
+ "width": 0,
75
+ },
76
+ "shadowOpacity": 0.12,
77
+ "shadowRadius": 2,
78
+ }
79
+ }
80
+ >
81
+ <View
82
+ style={
83
+ [
84
+ {},
85
+ [
86
+ {
87
+ "alignItems": "center",
88
+ "flexDirection": "row",
89
+ "gap": 8,
90
+ "justifyContent": "center",
91
+ },
92
+ undefined,
93
+ ],
94
+ ]
95
+ }
96
+ >
97
+ <View
98
+ style={
99
+ [
100
+ {},
101
+ [
102
+ {
103
+ "alignItems": "center",
104
+ "flexDirection": "row",
105
+ "gap": 4,
106
+ "justifyContent": "center",
107
+ },
108
+ undefined,
109
+ ],
110
+ ]
111
+ }
112
+ >
113
+ <Text
114
+ allowFontScaling={false}
115
+ style={
116
+ [
117
+ {
118
+ "color": "#001f23",
119
+ "fontFamily": "BeVietnamPro-SemiBold",
120
+ "fontSize": 14,
121
+ "letterSpacing": 0.24,
122
+ "lineHeight": 22,
123
+ },
124
+ [
125
+ {},
126
+ undefined,
127
+ ],
128
+ ]
129
+ }
130
+ themeIntent="body"
131
+ themeTypeface="neutral"
132
+ themeVariant="small-bold"
133
+ >
134
+ Option 1
135
+ </Text>
136
+ </View>
137
+ </View>
138
+ </View>
139
+ <View
140
+ accessibilityState={
141
+ {
142
+ "busy": undefined,
143
+ "checked": undefined,
144
+ "disabled": undefined,
145
+ "expanded": undefined,
146
+ "selected": undefined,
147
+ }
148
+ }
149
+ accessibilityValue={
150
+ {
151
+ "max": undefined,
152
+ "min": undefined,
153
+ "now": undefined,
154
+ "text": undefined,
155
+ }
156
+ }
157
+ accessible={true}
158
+ collapsable={false}
159
+ focusable={true}
160
+ onClick={[Function]}
161
+ onResponderGrant={[Function]}
162
+ onResponderMove={[Function]}
163
+ onResponderRelease={[Function]}
164
+ onResponderTerminate={[Function]}
165
+ onResponderTerminationRequest={[Function]}
166
+ onStartShouldSetResponder={[Function]}
167
+ style={
168
+ {
169
+ "alignItems": "center",
170
+ "backgroundColor": "transparent",
171
+ "borderRadius": 12,
172
+ "flexDirection": "row",
173
+ "flexGrow": 1,
174
+ "height": 28,
175
+ "justifyContent": "center",
176
+ "opacity": 1,
177
+ }
178
+ }
179
+ >
180
+ <View
181
+ style={
182
+ [
183
+ {},
184
+ [
185
+ {
186
+ "alignItems": "center",
187
+ "flexDirection": "row",
188
+ "gap": 8,
189
+ "justifyContent": "center",
190
+ },
191
+ undefined,
192
+ ],
193
+ ]
194
+ }
195
+ >
196
+ <View
197
+ style={
198
+ [
199
+ {},
200
+ [
201
+ {
202
+ "alignItems": "center",
203
+ "flexDirection": "row",
204
+ "gap": 4,
205
+ "justifyContent": "center",
206
+ },
207
+ undefined,
208
+ ],
209
+ ]
210
+ }
211
+ >
212
+ <Text
213
+ allowFontScaling={false}
214
+ style={
215
+ [
216
+ {
217
+ "color": "#808f91",
218
+ "fontFamily": "BeVietnamPro-SemiBold",
219
+ "fontSize": 14,
220
+ "letterSpacing": 0.24,
221
+ "lineHeight": 22,
222
+ },
223
+ [
224
+ {},
225
+ undefined,
226
+ ],
227
+ ]
228
+ }
229
+ themeIntent="inactive"
230
+ themeTypeface="neutral"
231
+ themeVariant="small-bold"
232
+ >
233
+ Option 2
234
+ </Text>
235
+ </View>
236
+ </View>
237
+ </View>
238
+ <View
239
+ accessibilityState={
240
+ {
241
+ "busy": undefined,
242
+ "checked": undefined,
243
+ "disabled": undefined,
244
+ "expanded": undefined,
245
+ "selected": undefined,
246
+ }
247
+ }
248
+ accessibilityValue={
249
+ {
250
+ "max": undefined,
251
+ "min": undefined,
252
+ "now": undefined,
253
+ "text": undefined,
254
+ }
255
+ }
256
+ accessible={true}
257
+ collapsable={false}
258
+ focusable={true}
259
+ onClick={[Function]}
260
+ onResponderGrant={[Function]}
261
+ onResponderMove={[Function]}
262
+ onResponderRelease={[Function]}
263
+ onResponderTerminate={[Function]}
264
+ onResponderTerminationRequest={[Function]}
265
+ onStartShouldSetResponder={[Function]}
266
+ style={
267
+ {
268
+ "alignItems": "center",
269
+ "backgroundColor": "transparent",
270
+ "borderRadius": 12,
271
+ "flexDirection": "row",
272
+ "flexGrow": 1,
273
+ "height": 28,
274
+ "justifyContent": "center",
275
+ "opacity": 1,
276
+ }
277
+ }
278
+ >
279
+ <View
280
+ style={
281
+ [
282
+ {},
283
+ [
284
+ {
285
+ "alignItems": "center",
286
+ "flexDirection": "row",
287
+ "gap": 8,
288
+ "justifyContent": "center",
289
+ },
290
+ undefined,
291
+ ],
292
+ ]
293
+ }
294
+ >
295
+ <View
296
+ style={
297
+ [
298
+ {},
299
+ [
300
+ {
301
+ "alignItems": "center",
302
+ "flexDirection": "row",
303
+ "gap": 4,
304
+ "justifyContent": "center",
305
+ },
306
+ undefined,
307
+ ],
308
+ ]
309
+ }
310
+ >
311
+ <Text
312
+ allowFontScaling={false}
313
+ style={
314
+ [
315
+ {
316
+ "color": "#808f91",
317
+ "fontFamily": "BeVietnamPro-SemiBold",
318
+ "fontSize": 14,
319
+ "letterSpacing": 0.24,
320
+ "lineHeight": 22,
321
+ },
322
+ [
323
+ {},
324
+ undefined,
325
+ ],
326
+ ]
327
+ }
328
+ themeIntent="inactive"
329
+ themeTypeface="neutral"
330
+ themeVariant="small-bold"
331
+ >
332
+ Option 3
333
+ </Text>
334
+ </View>
335
+ </View>
336
+ </View>
337
+ </View>
338
+ <View
339
+ pointerEvents="box-none"
340
+ position="bottom"
341
+ style={
342
+ [
343
+ {
344
+ "bottom": 0,
345
+ "elevation": 9999,
346
+ "flexDirection": "column-reverse",
347
+ "left": 0,
348
+ "paddingHorizontal": 24,
349
+ "paddingVertical": 16,
350
+ "position": "absolute",
351
+ "right": 0,
352
+ "top": 0,
353
+ },
354
+ undefined,
355
+ ]
356
+ }
357
+ />
358
+ </View>
359
+ `;