@hero-design/rn 8.72.0 → 8.73.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.
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import renderWithTheme from '../../../testHelpers/renderWithTheme';
3
+ import MapPin from '..';
4
+
5
+ describe('MapPin', () => {
6
+ it('renders icon correctly', () => {
7
+ const { getByTestId, toJSON } = renderWithTheme(
8
+ <MapPin icon="activate" testID="map-pin" />
9
+ );
10
+ expect(toJSON()).toMatchSnapshot();
11
+ expect(getByTestId('map-pin-icon')).toBeDefined();
12
+ });
13
+
14
+ it('renders image correctly', () => {
15
+ const { getByTestId, toJSON } = renderWithTheme(
16
+ <MapPin
17
+ image={{
18
+ source: {
19
+ uri: 'data:image/png;base64,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',
20
+ },
21
+ }}
22
+ testID="map-pin"
23
+ />
24
+ );
25
+ expect(toJSON()).toMatchSnapshot();
26
+ expect(getByTestId('map-pin-image')).toBeDefined();
27
+ });
28
+
29
+ it('renders selected state correctly', () => {
30
+ const { getByTestId, toJSON } = renderWithTheme(
31
+ <MapPin icon="activate" state="selected" testID="map-pin" />
32
+ );
33
+ expect(toJSON()).toMatchSnapshot();
34
+ expect(getByTestId('map-pin-badge')).toBeDefined();
35
+ });
36
+
37
+ it('renders applied state correctly', () => {
38
+ const { getByTestId, toJSON } = renderWithTheme(
39
+ <MapPin icon="activate" state="applied" testID="map-pin" />
40
+ );
41
+ expect(toJSON()).toMatchSnapshot();
42
+ expect(getByTestId('map-pin-badge')).toBeDefined();
43
+ });
44
+ });
@@ -0,0 +1,64 @@
1
+ import React from 'react';
2
+ import {
3
+ StyledContainer,
4
+ StyledBadge,
5
+ StyledImage,
6
+ StyledContent,
7
+ } from './StyledMapPin';
8
+ import Icon, { IconName } from '../Icon';
9
+ import { MapPinProps } from './types';
10
+ import MapPinFocussed from './Focussed';
11
+
12
+ const getBadgeIconName = (
13
+ state: 'idle' | 'selected' | 'applied'
14
+ ): IconName | undefined => {
15
+ const iconMap: Record<'idle' | 'selected' | 'applied', IconName | undefined> =
16
+ {
17
+ idle: undefined,
18
+ selected: 'checkmark',
19
+ applied: 'mail-outlined',
20
+ };
21
+ return iconMap[state];
22
+ };
23
+
24
+ const MapPin = ({
25
+ style,
26
+ testID,
27
+ state = 'idle',
28
+ image,
29
+ icon,
30
+ ...nativeProps
31
+ }: MapPinProps): JSX.Element => {
32
+ const badgeIcon = getBadgeIconName(state);
33
+ return (
34
+ <StyledContainer {...nativeProps} style={style} testID={testID}>
35
+ <StyledContent themeState={state} themeIsIcon={!!icon}>
36
+ {image && (
37
+ <StyledImage
38
+ testID={testID ? `${testID}-image` : undefined}
39
+ {...image}
40
+ />
41
+ )}
42
+ {icon && (
43
+ <Icon
44
+ icon={icon}
45
+ size="xsmall"
46
+ intent="text-inverted"
47
+ testID={testID ? `${testID}-icon` : undefined}
48
+ />
49
+ )}
50
+ </StyledContent>
51
+ {badgeIcon && (
52
+ <StyledBadge
53
+ icon={badgeIcon}
54
+ intent="primary"
55
+ testID={testID ? `${testID}-badge` : undefined}
56
+ />
57
+ )}
58
+ </StyledContainer>
59
+ );
60
+ };
61
+
62
+ export default Object.assign(MapPin, {
63
+ Focussed: MapPinFocussed,
64
+ });
@@ -0,0 +1,41 @@
1
+ import { ViewProps, StyleProp, ViewStyle, ImageProps } from 'react-native';
2
+ import { IconName } from '../Icon';
3
+
4
+ interface BaseMapPinProps extends ViewProps {
5
+ /**
6
+ * Additional style.
7
+ */
8
+ style?: StyleProp<ViewStyle>;
9
+ /**
10
+ * Testing id of the component.
11
+ */
12
+ testID?: string;
13
+ /**
14
+ * State of the map pin.
15
+ */
16
+ state?: 'idle' | 'selected' | 'applied';
17
+ }
18
+
19
+ interface ImageMapPinProps extends BaseMapPinProps {
20
+ /**
21
+ * Icon to display in the map pin.
22
+ */
23
+ icon?: never;
24
+ /**
25
+ * Image to display in the map pin.
26
+ */
27
+ image: ImageProps;
28
+ }
29
+
30
+ interface IconMapPinProps extends BaseMapPinProps {
31
+ /**
32
+ * Icon to display in the map pin.
33
+ */
34
+ icon: IconName;
35
+ /**
36
+ * Image to display in the map pin.
37
+ */
38
+ image?: never;
39
+ }
40
+
41
+ export type MapPinProps = ImageMapPinProps | IconMapPinProps;
@@ -82,6 +82,10 @@ describe('behaviors', () => {
82
82
 
83
83
  expect(onChangeText).toHaveBeenCalledWith('1234');
84
84
  expect(onFulfill).toHaveBeenCalledWith('1234');
85
+
86
+ fireEvent.changeText(hiddenInput, '56789');
87
+ expect(onChangeText).toHaveBeenCalledWith('5678');
88
+ expect(onFulfill).toHaveBeenCalledWith('5678');
85
89
  });
86
90
 
87
91
  it.each`
@@ -155,13 +155,17 @@ const PinInput = forwardRef<PinInputHandler, PinInputProps>(
155
155
  const slicedText = text.slice(length);
156
156
 
157
157
  onChangeText?.(normalizeValue(slicedText, length));
158
+
159
+ if (slicedText.length === length) {
160
+ onFulfill?.(slicedText);
161
+ }
158
162
  } else {
159
163
  // Prevent user from entering more than the length
160
164
  onChangeText?.(trimmedPin);
161
- }
162
165
 
163
- if (trimmedPin.length === length) {
164
- onFulfill?.(trimmedPin);
166
+ if (trimmedPin.length === length) {
167
+ onFulfill?.(trimmedPin);
168
+ }
165
169
  }
166
170
  },
167
171
  [length, onChangeText, onFulfill, trimmedValue.length]
package/src/index.ts CHANGED
@@ -38,6 +38,7 @@ import Empty from './components/Empty';
38
38
  import Error from './components/Error';
39
39
  import FAB from './components/FAB';
40
40
  import HeroDesignProvider from './components/HeroDesignProvider';
41
+ import MapPin from './components/MapPin';
41
42
  import Icon from './components/Icon';
42
43
  import Image from './components/Image';
43
44
  import List from './components/List';
@@ -114,6 +115,7 @@ export {
114
115
  Icon,
115
116
  Image,
116
117
  HeroDesignProvider,
118
+ MapPin,
117
119
  List,
118
120
  PinInput,
119
121
  Progress,
@@ -664,6 +664,44 @@ exports[`theme returns correct theme object 1`] = `
664
664
  "leadingStatus": 8,
665
665
  },
666
666
  },
667
+ "mapPin": {
668
+ "borderWidths": {
669
+ "default": 4,
670
+ },
671
+ "colors": {
672
+ "background": "#ffffff",
673
+ "badge": "#795e90",
674
+ "border": {
675
+ "applied": "#795e90",
676
+ "idle": "#ffffff",
677
+ "selected": "#795e90",
678
+ },
679
+ "iconBackground": "#4d6265",
680
+ },
681
+ "fontSizes": {
682
+ "icon": 42,
683
+ },
684
+ "radii": {
685
+ "default": 12,
686
+ },
687
+ "shadows": {
688
+ "color": "#001f23",
689
+ "elevation": 3,
690
+ "offset": {
691
+ "height": 2,
692
+ "width": 0,
693
+ },
694
+ "opacity": 0.12,
695
+ "radius": 4,
696
+ },
697
+ "sizes": {
698
+ "default": 42,
699
+ },
700
+ "space": {
701
+ "iconRight": -8,
702
+ "iconTop": -8,
703
+ },
704
+ },
667
705
  "pageControl": {
668
706
  "colors": {
669
707
  "paginatorBackgroundColor": "#401960",
@@ -0,0 +1,47 @@
1
+ import type { GlobalTheme } from '../global';
2
+
3
+ const getMapPinTheme = (theme: GlobalTheme) => {
4
+ const sizes = {
5
+ default: 42,
6
+ };
7
+
8
+ const fontSizes = {
9
+ icon: 42,
10
+ };
11
+
12
+ const borderWidths = {
13
+ default: theme.borderWidths.medium * 2,
14
+ };
15
+
16
+ const colors = {
17
+ border: {
18
+ idle: theme.colors.defaultGlobalSurface,
19
+ selected: theme.colors.secondary,
20
+ applied: theme.colors.secondary,
21
+ },
22
+ badge: theme.colors.secondary,
23
+ background: theme.colors.defaultGlobalSurface,
24
+ iconBackground: theme.colors.mutedOnDefaultGlobalSurface,
25
+ };
26
+
27
+ const radii = {
28
+ default: theme.radii.large,
29
+ };
30
+
31
+ const space = {
32
+ iconTop: -theme.space.small,
33
+ iconRight: -theme.space.small,
34
+ };
35
+
36
+ const shadows = {
37
+ offset: theme.shadows.default.shadowOffset,
38
+ opacity: theme.shadows.default.shadowOpacity,
39
+ radius: theme.shadows.default.shadowRadius,
40
+ elevation: theme.shadows.default.elevation,
41
+ color: theme.shadows.default.shadowColor,
42
+ };
43
+
44
+ return { sizes, colors, borderWidths, radii, shadows, space, fontSizes };
45
+ };
46
+
47
+ export default getMapPinTheme;
@@ -49,6 +49,7 @@ import getTypographyTheme from './components/typography';
49
49
 
50
50
  import type { GlobalTheme, Scale, SystemPalette } from './global';
51
51
  import getSearchTheme from './components/search';
52
+ import getMapPinTheme from './components/mapPin';
52
53
 
53
54
  type Theme = GlobalTheme & {
54
55
  __hd__: {
@@ -76,6 +77,7 @@ type Theme = GlobalTheme & {
76
77
  icon: ReturnType<typeof getIconTheme>;
77
78
  image: ReturnType<typeof getImageTheme>;
78
79
  list: ReturnType<typeof getListTheme>;
80
+ mapPin: ReturnType<typeof getMapPinTheme>;
79
81
  pageControl: ReturnType<typeof getPageControlTheme>;
80
82
  pinInput: PinInputThemeType;
81
83
  progress: ReturnType<typeof getProgressTheme>;
@@ -134,6 +136,7 @@ const getTheme = (
134
136
  icon: getIconTheme(globalTheme),
135
137
  image: getImageTheme(globalTheme),
136
138
  list: getListTheme(globalTheme),
139
+ mapPin: getMapPinTheme(globalTheme),
137
140
  pageControl: getPageControlTheme(globalTheme),
138
141
  pinInput: getPinInputTheme(globalTheme),
139
142
  progress: getProgressTheme(globalTheme),