@hero-design/rn 8.35.0 → 8.35.1

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.
@@ -10,52 +10,53 @@ describe('ActionGroup', () => {
10
10
  ${true}
11
11
  ${false}
12
12
  `('has active $active', ({ active }) => {
13
- const { toJSON, getByTestId, getByText } = renderWithTheme(
14
- <ActionGroup
15
- fabTitle="Shout out"
16
- active={active}
17
- headerTitle="What would you like to create?"
18
- items={[
19
- {
20
- icon: 'speaker',
21
- title: 'Give shout out',
22
- testID: 'speaker-action-item',
23
- },
24
- { icon: 'target', title: 'Goal', testID: 'target-action-item' },
25
- {
26
- icon: 'plane',
27
- title: 'Leave request',
28
- testID: 'plane-action-item',
29
- },
30
- {
31
- icon: 'health-bag',
32
- title: 'Safety incident',
33
- testID: 'health-bag-action-item',
34
- },
35
- { icon: 'clock', title: 'Timesheets', testID: 'clock-action-item' },
36
- ]}
37
- />
38
- );
13
+ const { toJSON, getByTestId, getByText, queryByTestId, queryByText } =
14
+ renderWithTheme(
15
+ <ActionGroup
16
+ fabTitle="Shout out"
17
+ active={active}
18
+ headerTitle="What would you like to create?"
19
+ items={[
20
+ {
21
+ icon: 'speaker',
22
+ title: 'Give shout out',
23
+ testID: 'speaker-action-item',
24
+ },
25
+ { icon: 'target', title: 'Goal', testID: 'target-action-item' },
26
+ {
27
+ icon: 'plane',
28
+ title: 'Leave request',
29
+ testID: 'plane-action-item',
30
+ },
31
+ {
32
+ icon: 'health-bag',
33
+ title: 'Safety incident',
34
+ testID: 'health-bag-action-item',
35
+ },
36
+ { icon: 'clock', title: 'Timesheets', testID: 'clock-action-item' },
37
+ ]}
38
+ />
39
+ );
39
40
 
40
41
  expect(toJSON()).toMatchSnapshot();
41
42
 
42
- expect(getByText('What would you like to create?')).toBeDefined();
43
- expect(getByTestId('speaker-action-item')).toBeDefined();
44
- expect(getByTestId('target-action-item')).toBeDefined();
45
- expect(getByTestId('plane-action-item')).toBeDefined();
46
- expect(getByTestId('health-bag-action-item')).toBeDefined();
47
-
48
43
  if (active) {
49
44
  // verify backdrop appears
50
- expect(getByTestId('back-drop')).toHaveProp('pointerEvents', 'auto');
45
+ expect(queryByTestId('back-drop')).toBeDefined();
46
+ expect(getByText('What would you like to create?')).toBeDefined();
47
+ expect(getByTestId('speaker-action-item')).toBeDefined();
48
+ expect(getByTestId('target-action-item')).toBeDefined();
49
+ expect(getByTestId('plane-action-item')).toBeDefined();
50
+ expect(getByTestId('health-bag-action-item')).toBeDefined();
51
51
  } else {
52
52
  // verify backdrop disappears
53
- expect(getByTestId('back-drop')).toHaveProp('pointerEvents', 'box-none');
53
+ expect(queryByTestId('back-drop')).toBeNull();
54
+ expect(queryByText('What would you like to create?')).toBeNull();
54
55
  }
55
56
  });
56
57
 
57
58
  describe('when user presses', () => {
58
- it('calls onPress', () => {
59
+ it('calls onPress when active = false', () => {
59
60
  const onPressSpy = jest.fn();
60
61
  const { getByTestId } = renderWithTheme(
61
62
  <ActionGroup onPress={onPressSpy} />
@@ -63,5 +64,14 @@ describe('ActionGroup', () => {
63
64
  fireEvent(getByTestId('fab'), 'press');
64
65
  expect(onPressSpy).toBeCalledTimes(1);
65
66
  });
67
+
68
+ it('calls onPress when active = true', () => {
69
+ const onPressSpy = jest.fn();
70
+ const { getByTestId } = renderWithTheme(
71
+ <ActionGroup onPress={onPressSpy} active />
72
+ );
73
+ fireEvent(getByTestId('fab-in-portal'), 'press');
74
+ expect(onPressSpy).toBeCalledTimes(1);
75
+ });
66
76
  });
67
77
  });
@@ -1,6 +1,6 @@
1
1
  import React, { forwardRef, useRef } from 'react';
2
2
  import type { StyleProp, ViewStyle } from 'react-native';
3
- import { Animated, Platform } from 'react-native';
3
+ import { Animated, Platform, Modal } from 'react-native';
4
4
  import type { IconName } from '../../Icon';
5
5
  import type { ActionItemProps } from './ActionItem';
6
6
  import ActionItem from './ActionItem';
@@ -8,6 +8,7 @@ import {
8
8
  StyledActionGroupContainer,
9
9
  StyledBackdrop,
10
10
  StyledContainer,
11
+ StyledContainerInModal,
11
12
  StyledFAB,
12
13
  StyledHeaderText,
13
14
  } from './StyledActionGroup';
@@ -110,64 +111,83 @@ const ActionGroup = forwardRef<ActionGroupHandles, ActionGroupProps>(
110
111
  }),
111
112
  ]).start();
112
113
  }, [active]);
113
-
114
- const interpolatedBackdropOpacityAnimation =
114
+ const interpolatedActionGroupOpacityAnimation =
115
115
  tranlateXAnimation.current.interpolate({
116
116
  inputRange: [0, 1],
117
- outputRange: [0, 0.25],
117
+ outputRange: [0, 1],
118
118
  });
119
119
 
120
- const interpolatedActionGroupOpacityAnimation =
120
+ const interpolatedFABOpacityAnimation =
121
121
  tranlateXAnimation.current.interpolate({
122
122
  inputRange: [0, 1],
123
- outputRange: [0, 1],
123
+ outputRange: [1, 0],
124
124
  });
125
125
 
126
126
  return (
127
127
  <StyledContainer testID={testID} pointerEvents="box-none" style={style}>
128
- <StyledBackdrop
129
- pointerEvents={active ? 'auto' : 'box-none'}
130
- testID="back-drop"
131
- style={{ opacity: interpolatedBackdropOpacityAnimation }}
132
- />
133
- <StyledActionGroupContainer
134
- pointerEvents={active ? 'auto' : 'none'}
135
- testID="action-group"
128
+ <Animated.View
136
129
  style={{
137
- opacity: interpolatedActionGroupOpacityAnimation,
130
+ opacity: interpolatedFABOpacityAnimation,
138
131
  }}
139
132
  >
140
- {!!headerTitle && (
141
- <Animated.View
142
- style={{ transform: [{ translateY: titleTranslateY }] }}
133
+ <StyledFAB
134
+ key="fab"
135
+ testID="fab"
136
+ icon={fabIcon}
137
+ onPress={onPress}
138
+ animated
139
+ active={active}
140
+ title={fabTitle}
141
+ ref={fabRef}
142
+ />
143
+ </Animated.View>
144
+ <Modal
145
+ visible={active}
146
+ animationType="fade"
147
+ transparent
148
+ statusBarTranslucent
149
+ >
150
+ <StyledContainerInModal testID={testID} style={[style]}>
151
+ <StyledBackdrop testID="back-drop" />
152
+ <StyledActionGroupContainer
153
+ testID="action-group"
154
+ style={{
155
+ opacity: interpolatedActionGroupOpacityAnimation,
156
+ }}
143
157
  >
144
- <StyledHeaderText testID="header-text" level="h4">
145
- {headerTitle}
146
- </StyledHeaderText>
147
- </Animated.View>
148
- )}
149
-
150
- <Box style={[style, { paddingBottom: 0 }]}>
151
- {items?.map((itemProp, index) => (
152
- <ActionItem
153
- key={itemProp.key || `${itemProp.icon}_${itemProp.title}`}
154
- {...itemProp}
155
- index={active ? index : items.length - index}
156
- active={active}
157
- />
158
- ))}
159
- </Box>
160
- </StyledActionGroupContainer>
161
-
162
- <StyledFAB
163
- testID="fab"
164
- icon={fabIcon}
165
- onPress={onPress}
166
- animated
167
- active={active}
168
- title={fabTitle}
169
- ref={fabRef}
170
- />
158
+ {!!headerTitle && (
159
+ <Animated.View
160
+ style={{ transform: [{ translateY: titleTranslateY }] }}
161
+ >
162
+ <StyledHeaderText testID="header-text" level="h4">
163
+ {headerTitle}
164
+ </StyledHeaderText>
165
+ </Animated.View>
166
+ )}
167
+
168
+ <Box style={[style, { paddingBottom: 0 }]}>
169
+ {items?.map((itemProp, index) => (
170
+ <ActionItem
171
+ key={itemProp.key || `${itemProp.icon}_${itemProp.title}`}
172
+ {...itemProp}
173
+ index={active ? index : items.length - index}
174
+ active={active}
175
+ />
176
+ ))}
177
+ </Box>
178
+ </StyledActionGroupContainer>
179
+
180
+ <StyledFAB
181
+ key="fab-in-portal"
182
+ testID="fab-in-portal"
183
+ icon={fabIcon}
184
+ onPress={onPress}
185
+ animated
186
+ active={active}
187
+ title={fabTitle}
188
+ />
189
+ </StyledContainerInModal>
190
+ </Modal>
171
191
  </StyledContainer>
172
192
  );
173
193
  }
@@ -4,6 +4,9 @@ import { usePortalState } from './usePortalState';
4
4
  import { PortalType } from './contexts';
5
5
 
6
6
  export interface PortalHostProps {
7
+ /*
8
+ * Name of the portal
9
+ * */
7
10
  name: string;
8
11
  }
9
12
  const PortalHostComponent = ({ name }: PortalHostProps) => {
@@ -6,7 +6,13 @@ import { INITIAL_STATE } from './constants';
6
6
  import { PortalDispatchContext, PortalStateContext } from './contexts';
7
7
 
8
8
  export interface PortalProviderProps {
9
+ /*
10
+ * The name of the root host
11
+ */
9
12
  rootHostName?: string;
13
+ /*
14
+ * The children to render
15
+ */
10
16
  children: ReactNode | ReactNode[];
11
17
  }
12
18
 
@@ -9,8 +9,19 @@ import { PortalHost } from './PortalHost';
9
9
  const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz0123456789', 10);
10
10
 
11
11
  export interface PortalProps {
12
+ /*
13
+ * Name of the portal. If name is not provided, a random name will be generated.
14
+ */
12
15
  name?: string;
16
+
17
+ /*
18
+ * Name of the portal host. If name is not provided, a default host will be used.
19
+ */
13
20
  hostName?: string;
21
+
22
+ /*
23
+ * Content of the portal.
24
+ */
14
25
  children?: ReactNode | ReactNode[];
15
26
  }
16
27
 
@@ -8,6 +8,12 @@ declare const StyledContainer: import("@emotion/native").StyledComponent<ViewPro
8
8
  }, {}, {
9
9
  ref?: import("react").Ref<View> | undefined;
10
10
  }>;
11
+ declare const StyledContainerInModal: import("@emotion/native").StyledComponent<ViewProps & {
12
+ theme?: import("@emotion/react").Theme | undefined;
13
+ as?: import("react").ElementType<any> | undefined;
14
+ }, {}, {
15
+ ref?: import("react").Ref<View> | undefined;
16
+ }>;
11
17
  declare const StyledActionGroupContainer: import("@emotion/native").StyledComponent<Animated.AnimatedProps<ViewProps & import("react").RefAttributes<View>> & {
12
18
  children?: import("react").ReactNode;
13
19
  } & {
@@ -28,4 +34,4 @@ declare const StyledHeaderText: import("@emotion/native").StyledComponent<import
28
34
  theme?: import("@emotion/react").Theme | undefined;
29
35
  as?: import("react").ElementType<any> | undefined;
30
36
  } & TextProps, {}, {}>;
31
- export { StyledHeaderText, StyledBackdrop, StyledContainer, StyledActionGroupContainer, StyledFAB, };
37
+ export { StyledHeaderText, StyledBackdrop, StyledContainer, StyledContainerInModal, StyledActionGroupContainer, StyledFAB, };