@hero-design/rn 8.92.2 → 8.93.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 (72) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/CHANGELOG.md +28 -0
  3. package/assets/fonts/hero-icons-mobile.ttf +0 -0
  4. package/es/index.js +689 -752
  5. package/lib/assets/fonts/hero-icons-mobile.ttf +0 -0
  6. package/lib/index.js +690 -752
  7. package/package.json +4 -2
  8. package/rollup.config.mjs +1 -0
  9. package/src/components/Badge/Count.tsx +60 -0
  10. package/src/components/Badge/StyledBadge.tsx +33 -2
  11. package/src/components/Badge/__tests__/Count.spec.tsx +38 -0
  12. package/src/components/Badge/__tests__/__snapshots__/Count.spec.tsx.snap +310 -0
  13. package/src/components/Badge/constants.ts +1 -0
  14. package/src/components/Badge/index.tsx +3 -2
  15. package/src/components/Button/StyledButton.tsx +15 -8
  16. package/src/components/Button/UtilityButton/StyledUtilityButton.tsx +5 -3
  17. package/src/components/Button/UtilityButton/__tests__/__snapshots__/index.spec.tsx.snap +4 -0
  18. package/src/components/Button/__tests__/__snapshots__/Button.spec.tsx.snap +61 -4
  19. package/src/components/Button/__tests__/__snapshots__/StyledButton.spec.tsx.snap +26 -0
  20. package/src/components/Carousel/__tests__/__snapshots__/index.spec.tsx.snap +6 -0
  21. package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +2 -0
  22. package/src/components/Icon/HeroIcon/glyphMap.json +1 -1
  23. package/src/components/Icon/IconList.ts +2 -0
  24. package/src/components/MapPin/StyledMapPin.tsx +1 -9
  25. package/src/components/Progress/ProgressCircle.tsx +53 -109
  26. package/src/components/Progress/StyledProgressBar.tsx +4 -1
  27. package/src/components/Progress/StyledProgressCircle.tsx +1 -57
  28. package/src/components/Progress/StyledStep.tsx +1 -1
  29. package/src/components/Progress/__tests__/__snapshots__/index.spec.js.snap +299 -647
  30. package/src/components/Search/SearchOneLine.tsx +2 -2
  31. package/src/components/Search/SearchTwoLine.tsx +1 -1
  32. package/src/components/Search/StyledSearch.tsx +20 -35
  33. package/src/components/Search/__tests__/__snapshots__/SearchOneLine.spec.tsx.snap +51 -51
  34. package/src/components/Search/__tests__/__snapshots__/SearchSuffixIcon.spec.tsx.snap +2 -2
  35. package/src/components/Search/__tests__/__snapshots__/SearchTwoLine.spec.tsx.snap +13 -15
  36. package/src/components/Search/__tests__/__snapshots__/utils.spec.tsx.snap +4 -4
  37. package/src/components/Search/utils.tsx +2 -2
  38. package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +5 -0
  39. package/src/components/Tabs/TabWithBadge.tsx +1 -1
  40. package/src/components/Tabs/__tests__/__snapshots__/ScrollableTabs.spec.tsx.snap +15 -9
  41. package/src/components/Tabs/__tests__/__snapshots__/ScrollableTabsHeader.spec.tsx.snap +6 -6
  42. package/src/components/Tabs/__tests__/__snapshots__/TabWithBadge.spec.tsx.snap +3 -3
  43. package/src/components/Tabs/__tests__/__snapshots__/index.spec.tsx.snap +15 -9
  44. package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +1 -0
  45. package/src/components/Toolbar/StyledToolbar.tsx +1 -0
  46. package/src/components/Toolbar/ToolbarMessage.tsx +3 -0
  47. package/src/components/Toolbar/__tests__/__snapshots__/ToolbarMessage.spec.tsx.snap +8 -0
  48. package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +31 -23
  49. package/src/theme/components/badge.ts +26 -1
  50. package/src/theme/components/button.ts +10 -0
  51. package/src/theme/components/progress.ts +21 -26
  52. package/src/theme/components/search.ts +2 -10
  53. package/src/theme/components/toolbar.ts +2 -0
  54. package/src/utils/helpers.ts +9 -0
  55. package/stats/8.92.3/rn-stats.html +4842 -0
  56. package/types/components/Badge/Count.d.ts +27 -0
  57. package/types/components/Badge/StyledBadge.d.ts +14 -4
  58. package/types/components/Badge/constants.d.ts +1 -0
  59. package/types/components/Badge/index.d.ts +1 -0
  60. package/types/components/Button/StyledButton.d.ts +2 -2
  61. package/types/components/Button/UtilityButton/StyledUtilityButton.d.ts +1 -1
  62. package/types/components/Icon/IconList.d.ts +1 -1
  63. package/types/components/Icon/index.d.ts +1 -1
  64. package/types/components/Progress/StyledProgressCircle.d.ts +1 -32
  65. package/types/components/Search/StyledSearch.d.ts +0 -1
  66. package/types/components/TextInput/index.d.ts +1 -1
  67. package/types/theme/components/badge.d.ts +11 -0
  68. package/types/theme/components/button.d.ts +3 -0
  69. package/types/theme/components/progress.d.ts +6 -6
  70. package/types/theme/components/search.d.ts +2 -10
  71. package/types/theme/components/toolbar.d.ts +2 -0
  72. package/types/utils/helpers.d.ts +1 -0
@@ -1,17 +1,12 @@
1
1
  import { useTheme } from '@emotion/react';
2
2
  import React, { useEffect, useRef } from 'react';
3
- import { Animated, View, StyleSheet } from 'react-native';
3
+ import { Animated, Easing, View } from 'react-native';
4
+ import Svg, { Circle, G } from 'react-native-svg';
4
5
  import type { ViewProps, StyleProp, ViewStyle } from 'react-native';
5
- import {
6
- StyledContainer,
7
- StyledDonutCircle,
8
- StyledHalfCircleInnerFG,
9
- StyledHalfCircleInnerBG,
10
- StyledHalfCircleWrapper,
11
- StyledStrokeEnd,
12
- } from './StyledProgressCircle';
6
+ import { StyledContainer, StyledDonutCircle } from './StyledProgressCircle';
13
7
  import Typography from '../Typography';
14
- import type { ThemeIntent } from './types';
8
+ import { THEME_INTENT_MAP } from './constants';
9
+ import { hexToRgba } from '../../utils/helpers';
15
10
 
16
11
  export interface ProgressCircleProps extends ViewProps {
17
12
  /**
@@ -48,23 +43,8 @@ export interface ProgressCircleProps extends ViewProps {
48
43
  testID?: string;
49
44
  }
50
45
 
51
- const HalfCircle = ({
52
- type,
53
- themeIntent,
54
- }: {
55
- type: 'background' | 'foreground';
56
- themeIntent: ThemeIntent;
57
- }) => (
58
- <StyledHalfCircleWrapper>
59
- {type === 'background' ? (
60
- <StyledHalfCircleInnerBG themeIntent={themeIntent} />
61
- ) : (
62
- <StyledHalfCircleInnerFG themeIntent={themeIntent} />
63
- )}
64
- </StyledHalfCircleWrapper>
65
- );
66
-
67
46
  const defaultRenderValue = (value: number) => `${value}%`;
47
+ const AnimatedCircle = Animated.createAnimatedComponent(Circle);
68
48
 
69
49
  const ProgressCircle = ({
70
50
  value,
@@ -75,101 +55,65 @@ const ProgressCircle = ({
75
55
  ...nativeProps
76
56
  }: ProgressCircleProps): JSX.Element => {
77
57
  const theme = useTheme();
78
- const radius = theme.__hd__.progress.sizes.circleDiameter / 2;
79
- const progressAnimatedValue = useRef<Animated.Value>(new Animated.Value(0));
58
+ const size = theme.__hd__.progress.sizes.circleDiameter;
59
+ const strokeWidth = theme.__hd__.progress.sizes.circleCompletenessHeight;
60
+ const radius = size / 2 - strokeWidth;
61
+ const circumference = 2 * Math.PI * radius;
62
+
63
+ const progressAnimatedValue = useRef(new Animated.Value(0)).current;
64
+ const minArc = strokeWidth / 2 / Math.PI; // Minimum arc length
80
65
 
81
66
  useEffect(() => {
82
- const animation = Animated.timing(progressAnimatedValue.current, {
67
+ Animated.timing(progressAnimatedValue, {
83
68
  toValue: value,
84
69
  useNativeDriver: true,
85
- });
86
-
87
- animation.start();
88
-
89
- return () => animation.stop();
70
+ easing: Easing.inOut(Easing.ease),
71
+ }).start();
90
72
  }, [value]);
91
73
 
92
- // Animate progress circle: 0% => 50%
93
- const interpolateRotateRightHalf = progressAnimatedValue.current.interpolate({
94
- inputRange: [0, 50],
95
- outputRange: ['0deg', '180deg'],
96
- extrapolate: 'clamp',
97
- });
98
-
99
- const interpolateOpacityRightHalf = progressAnimatedValue.current.interpolate(
100
- {
101
- inputRange: [50, 51], // Transition between left and right half
102
- outputRange: [1, 0],
103
- extrapolate: 'clamp',
104
- }
105
- );
106
-
107
- // Animate progress circle: 50% => 100%
108
- const interpolateRotateSecondHalf = progressAnimatedValue.current.interpolate(
109
- {
110
- inputRange: [50, 100],
111
- outputRange: ['0deg', '180deg'],
112
- extrapolate: 'clamp',
113
- }
114
- );
115
-
116
- // Curve at the end of progress stroke
117
- const interpolateDotRotate = progressAnimatedValue.current.interpolate({
74
+ const strokeDashoffset = progressAnimatedValue.interpolate({
118
75
  inputRange: [0, 100],
119
- outputRange: ['0deg', '360deg'],
120
- extrapolate: 'clamp',
76
+ outputRange: [circumference - minArc, 0], // Full circle to zero offset
121
77
  });
122
78
 
123
79
  return (
124
80
  <View {...nativeProps} testID={testID} style={style}>
125
81
  <StyledContainer>
126
- <View>
127
- <HalfCircle type="foreground" themeIntent={intent} />
128
- <Animated.View
129
- style={{
130
- ...StyleSheet.absoluteFillObject,
131
- transform: [
132
- { translateX: radius / 2 },
133
- { rotate: interpolateRotateSecondHalf },
134
- { translateX: -radius / 2 },
135
- ],
136
- }}
137
- >
138
- <HalfCircle type="background" themeIntent={intent} />
139
- </Animated.View>
140
- </View>
141
- <View
142
- style={{
143
- transform: [{ rotate: '180deg' }],
144
- zIndex: 1,
145
- marginLeft: -0.1,
146
- }}
147
- >
148
- <HalfCircle type="foreground" themeIntent={intent} />
149
- <Animated.View
150
- style={{
151
- ...StyleSheet.absoluteFillObject,
152
- transform: [
153
- { translateX: radius / 2 },
154
- { rotate: interpolateRotateRightHalf },
155
- { translateX: -radius / 2 },
156
- ],
157
- opacity: interpolateOpacityRightHalf,
158
- }}
159
- >
160
- <HalfCircle type="background" themeIntent={intent} />
161
- </Animated.View>
162
- </View>
163
- <StyledStrokeEnd themeIntent={intent} />
164
- <Animated.View
165
- style={{
166
- ...StyleSheet.absoluteFillObject,
167
- zIndex: 2,
168
- transform: [{ rotate: interpolateDotRotate }],
169
- }}
170
- >
171
- <StyledStrokeEnd themeIntent={intent} />
172
- </Animated.View>
82
+ <Svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
83
+ {/* rotation -90 in order to move start point from 3 o'clock to 12 o'clock */}
84
+ <G rotation="-90" origin={`${size / 2}, ${size / 2}`}>
85
+ {/* Background Circle */}
86
+ <Circle
87
+ cx={size / 2}
88
+ cy={size / 2}
89
+ r={radius}
90
+ stroke={hexToRgba(
91
+ theme.__hd__.progress.colors.incompleteness[
92
+ THEME_INTENT_MAP[intent]
93
+ ],
94
+ 0.1
95
+ )}
96
+ strokeWidth={strokeWidth}
97
+ fill="transparent"
98
+ />
99
+ {/* Progress Circle */}
100
+ <AnimatedCircle
101
+ cx={size / 2}
102
+ cy={size / 2}
103
+ r={radius}
104
+ stroke={
105
+ theme.__hd__.progress.colors.completeness[
106
+ THEME_INTENT_MAP[intent]
107
+ ]
108
+ }
109
+ strokeWidth={strokeWidth}
110
+ fill="transparent"
111
+ strokeDasharray={circumference}
112
+ strokeDashoffset={strokeDashoffset}
113
+ strokeLinecap="round"
114
+ />
115
+ </G>
116
+ </Svg>
173
117
  <StyledDonutCircle>
174
118
  <Typography.Body>{renderValue(value)}</Typography.Body>
175
119
  </StyledDonutCircle>
@@ -3,15 +3,18 @@ import styled from '@emotion/native';
3
3
  import type { ViewProps } from 'react-native';
4
4
  import type { ThemeIntent } from './types';
5
5
  import { THEME_INTENT_MAP } from './constants';
6
+ import { hexToRgba } from '../../utils/helpers';
6
7
 
7
8
  const StyledWrapper = styled(View)<ViewProps & { themeIntent: ThemeIntent }>(
8
9
  ({ theme, themeIntent }) => ({
9
10
  height: theme.__hd__.progress.sizes.barHeight,
10
11
  alignSelf: 'stretch',
11
- backgroundColor:
12
+ backgroundColor: hexToRgba(
12
13
  theme.__hd__.progress.colors.incompleteness[
13
14
  THEME_INTENT_MAP[themeIntent]
14
15
  ],
16
+ 0.1
17
+ ),
15
18
  overflow: 'hidden',
16
19
  borderRadius: theme.__hd__.progress.radii.default,
17
20
  })
@@ -1,44 +1,12 @@
1
1
  import { View } from 'react-native';
2
2
  import styled from '@emotion/native';
3
3
  import type { ViewProps } from 'react-native';
4
- import type { ThemeIntent } from './types';
5
- import { THEME_INTENT_MAP } from './constants';
6
4
 
7
5
  const StyledContainer = styled(View)<ViewProps>(({ theme }) => ({
8
6
  flexDirection: 'row',
9
7
  borderRadius: theme.__hd__.progress.radii.default,
10
8
  }));
11
9
 
12
- const StyledHalfCircleWrapper = styled(View)<ViewProps>(({ theme }) => ({
13
- width: theme.__hd__.progress.sizes.circleDiameter / 2,
14
- height: theme.__hd__.progress.sizes.circleDiameter,
15
- overflow: 'hidden',
16
- }));
17
-
18
- const StyledHalfCircleInnerFG = styled(View)<{ themeIntent: ThemeIntent }>(
19
- ({ theme, themeIntent }) => ({
20
- width: theme.__hd__.progress.sizes.circleDiameter,
21
- height: theme.__hd__.progress.sizes.circleDiameter,
22
- borderRadius: theme.__hd__.progress.radii.default,
23
- borderColor:
24
- theme.__hd__.progress.colors.completeness[THEME_INTENT_MAP[themeIntent]],
25
- borderWidth: theme.__hd__.progress.sizes.circleCompletenessHeight,
26
- })
27
- );
28
-
29
- const StyledHalfCircleInnerBG = styled(View)<{ themeIntent: ThemeIntent }>(
30
- ({ theme, themeIntent }) => ({
31
- width: theme.__hd__.progress.sizes.circleDiameter,
32
- height: theme.__hd__.progress.sizes.circleDiameter,
33
- borderRadius: theme.__hd__.progress.radii.default,
34
- borderWidth: theme.__hd__.progress.sizes.circleCompletenessHeight,
35
- borderColor:
36
- theme.__hd__.progress.colors.incompleteness[
37
- THEME_INTENT_MAP[themeIntent]
38
- ],
39
- })
40
- );
41
-
42
10
  const StyledDonutCircle = styled(View)<ViewProps>(({ theme }) => ({
43
11
  position: 'absolute',
44
12
  top: theme.__hd__.progress.sizes.circleCompletenessHeight,
@@ -55,28 +23,4 @@ const StyledDonutCircle = styled(View)<ViewProps>(({ theme }) => ({
55
23
  justifyContent: 'center',
56
24
  }));
57
25
 
58
- const StyledStrokeEnd = styled(View)<{ themeIntent: ThemeIntent }>(
59
- ({ theme, themeIntent }) => ({
60
- position: 'absolute',
61
- top: 0,
62
- left:
63
- (theme.__hd__.progress.sizes.circleDiameter -
64
- theme.__hd__.progress.sizes.circleCompletenessHeight) /
65
- 2,
66
- width: theme.__hd__.progress.sizes.circleCompletenessHeight,
67
- height: theme.__hd__.progress.sizes.circleCompletenessHeight,
68
- borderRadius: theme.__hd__.progress.radii.default,
69
- backgroundColor:
70
- theme.__hd__.progress.colors.completeness[THEME_INTENT_MAP[themeIntent]],
71
- zIndex: 2,
72
- })
73
- );
74
-
75
- export {
76
- StyledContainer,
77
- StyledDonutCircle,
78
- StyledHalfCircleWrapper,
79
- StyledHalfCircleInnerFG,
80
- StyledHalfCircleInnerBG,
81
- StyledStrokeEnd,
82
- };
26
+ export { StyledContainer, StyledDonutCircle };
@@ -23,7 +23,7 @@ const StyledStep = styled(Box)<{
23
23
  const StyledSingleStepContainer = styled(Box)(({ theme }) => ({
24
24
  height: theme.__hd__.progress.sizes.stepHeight,
25
25
  borderRadius: theme.__hd__.progress.radii.default,
26
- backgroundColor: theme.__hd__.progress.colors.step.current,
26
+ backgroundColor: theme.__hd__.progress.colors.step.incomplete,
27
27
  width: '100%',
28
28
  position: 'relative',
29
29
  }));