@hero-design/rn 8.34.2-alpha.0 → 8.35.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +18 -7
- package/es/index.js +11417 -2305
- package/lib/index.js +11418 -2305
- package/package.json +6 -6
- package/rollup.config.js +3 -7
- package/src/components/Avatar/AvatarStack/__tests__/__snapshots__/index.spec.tsx.snap +9 -9
- package/src/components/FAB/ActionGroup/FABModal.tsx +63 -0
- package/src/components/FAB/ActionGroup/FABModalContentWrapper.tsx +31 -0
- package/src/components/FAB/ActionGroup/ModalPresenter/ModalPresenter.tsx +133 -0
- package/src/components/FAB/ActionGroup/ModalPresenter/index.tsx +13 -0
- package/src/components/FAB/ActionGroup/__tests__/__snapshots__/index.spec.tsx.snap +2 -2
- package/src/components/FAB/ActionGroup/index.tsx +49 -47
- package/src/components/FAB/FAB.tsx +1 -0
- package/src/components/FAB/StyledFAB.tsx +20 -16
- package/src/components/FAB/__tests__/StyledFAB.spec.tsx +11 -1
- package/src/components/FAB/__tests__/__snapshots__/StyledFAB.spec.tsx.snap +57 -0
- package/src/components/List/StyledListItem.tsx +1 -1
- package/src/components/List/__tests__/__snapshots__/ListItem.spec.tsx.snap +4 -0
- package/src/components/List/__tests__/__snapshots__/StyledListItem.spec.tsx.snap +2 -0
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +2 -1
- package/src/theme/components/fab.ts +1 -0
- package/src/theme/components/list.ts +1 -1
- package/src/theme/global/colors/__tests__/__snapshots__/work.spec.ts.snap +4 -4
- package/src/theme/global/colors/work.ts +4 -4
- package/types/components/FAB/ActionGroup/FABModal.d.ts +21 -0
- package/types/components/FAB/ActionGroup/FABModalContentWrapper.d.ts +18 -0
- package/types/components/FAB/ActionGroup/FABProvider.d.ts +5 -0
- package/types/components/FAB/ActionGroup/ModalPresenter/ModalPresenter.d.ts +34 -0
- package/types/components/FAB/ActionGroup/ModalPresenter/index.d.ts +3 -0
- package/types/components/FAB/StyledFAB.d.ts +2 -0
- package/types/theme/components/fab.d.ts +1 -0
- package/types/theme/components/list.d.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hero-design/rn",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.35.0-alpha.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "es/index.js",
|
|
@@ -22,12 +22,9 @@
|
|
|
22
22
|
"@emotion/native": "^11.9.3",
|
|
23
23
|
"@emotion/react": "^11.9.3",
|
|
24
24
|
"@hero-design/colors": "8.34.1",
|
|
25
|
-
"@hero-design/react-native-month-year-picker": "^8.34.1",
|
|
26
25
|
"date-fns": "^2.16.1",
|
|
27
26
|
"events": "^3.2.0",
|
|
28
|
-
"hero-editor": "^1.9.21"
|
|
29
|
-
"react-native-root-siblings": "^4.1.1",
|
|
30
|
-
"rollup-plugin-jsx": "^1.0.3"
|
|
27
|
+
"hero-editor": "^1.9.21"
|
|
31
28
|
},
|
|
32
29
|
"peerDependencies": {
|
|
33
30
|
"@hero-design/react-native-month-year-picker": "^8.34.1",
|
|
@@ -38,6 +35,7 @@
|
|
|
38
35
|
"react-native-gesture-handler": "^1.10.3 | ~2.5.0",
|
|
39
36
|
"react-native-linear-gradient": "^2.6.2",
|
|
40
37
|
"react-native-pager-view": "^5.4.25",
|
|
38
|
+
"react-native-root-siblings": "^4.1.1",
|
|
41
39
|
"react-native-safe-area-context": "^3.0.2",
|
|
42
40
|
"react-native-vector-icons": "^9.1.0",
|
|
43
41
|
"react-native-webview": "^11.2.5"
|
|
@@ -50,6 +48,7 @@
|
|
|
50
48
|
"@babel/runtime": "^7.18.9",
|
|
51
49
|
"@emotion/jest": "^11.9.3",
|
|
52
50
|
"@hero-design/eslint-plugin": "8.34.1",
|
|
51
|
+
"@hero-design/react-native-month-year-picker": "^8.34.1",
|
|
53
52
|
"@react-native-community/datetimepicker": "^3.5.2",
|
|
54
53
|
"@react-native-community/slider": "4.1.12",
|
|
55
54
|
"@rollup/plugin-babel": "^5.3.1",
|
|
@@ -83,5 +82,6 @@
|
|
|
83
82
|
"rollup-plugin-flow": "^1.1.1",
|
|
84
83
|
"ts-jest": "^27.0.7"
|
|
85
84
|
},
|
|
86
|
-
"prettier": "prettier-config-hd"
|
|
85
|
+
"prettier": "prettier-config-hd",
|
|
86
|
+
"react-native": "src/index.ts"
|
|
87
87
|
}
|
package/rollup.config.js
CHANGED
|
@@ -35,6 +35,7 @@ export default {
|
|
|
35
35
|
'react-native-vector-icons',
|
|
36
36
|
'react-native-linear-gradient',
|
|
37
37
|
'@hero-design/react-native-month-year-picker',
|
|
38
|
+
'react-native-root-siblings',
|
|
38
39
|
],
|
|
39
40
|
plugins: [
|
|
40
41
|
replace({
|
|
@@ -42,15 +43,10 @@ export default {
|
|
|
42
43
|
}),
|
|
43
44
|
nodeResolve({ extensions, browser: true }),
|
|
44
45
|
flow(),
|
|
46
|
+
commonjs(),
|
|
45
47
|
json(),
|
|
46
48
|
typescript(),
|
|
47
|
-
babel({
|
|
48
|
-
exclude: 'node_modules/**',
|
|
49
|
-
presets: ['@babel/env', '@babel/preset-react'],
|
|
50
|
-
extensions,
|
|
51
|
-
babelHelpers: 'bundled',
|
|
52
|
-
}),
|
|
53
|
-
commonjs(),
|
|
49
|
+
babel({ extensions, babelHelpers: 'bundled' }),
|
|
54
50
|
copy({
|
|
55
51
|
targets: [
|
|
56
52
|
{
|
|
@@ -34,7 +34,7 @@ exports[`AvatarStack renders correctly by default 1`] = `
|
|
|
34
34
|
onStartShouldSetResponder={[Function]}
|
|
35
35
|
style={
|
|
36
36
|
Object {
|
|
37
|
-
"backgroundColor": "#
|
|
37
|
+
"backgroundColor": "#001f23",
|
|
38
38
|
"borderRadius": 999,
|
|
39
39
|
"height": 32,
|
|
40
40
|
"left": 0,
|
|
@@ -111,7 +111,7 @@ exports[`AvatarStack renders correctly by default 1`] = `
|
|
|
111
111
|
onStartShouldSetResponder={[Function]}
|
|
112
112
|
style={
|
|
113
113
|
Object {
|
|
114
|
-
"backgroundColor": "#
|
|
114
|
+
"backgroundColor": "#0d2a2e",
|
|
115
115
|
"borderRadius": 999,
|
|
116
116
|
"height": 32,
|
|
117
117
|
"left": 22.4,
|
|
@@ -188,7 +188,7 @@ exports[`AvatarStack renders correctly by default 1`] = `
|
|
|
188
188
|
onStartShouldSetResponder={[Function]}
|
|
189
189
|
style={
|
|
190
190
|
Object {
|
|
191
|
-
"backgroundColor": "#
|
|
191
|
+
"backgroundColor": "#193539",
|
|
192
192
|
"borderRadius": 999,
|
|
193
193
|
"height": 32,
|
|
194
194
|
"left": 44.8,
|
|
@@ -265,7 +265,7 @@ exports[`AvatarStack renders correctly by default 1`] = `
|
|
|
265
265
|
onStartShouldSetResponder={[Function]}
|
|
266
266
|
style={
|
|
267
267
|
Object {
|
|
268
|
-
"backgroundColor": "#
|
|
268
|
+
"backgroundColor": "#264144",
|
|
269
269
|
"borderRadius": 999,
|
|
270
270
|
"height": 32,
|
|
271
271
|
"left": 67.19999999999999,
|
|
@@ -342,7 +342,7 @@ exports[`AvatarStack renders correctly by default 1`] = `
|
|
|
342
342
|
onStartShouldSetResponder={[Function]}
|
|
343
343
|
style={
|
|
344
344
|
Object {
|
|
345
|
-
"backgroundColor": "#
|
|
345
|
+
"backgroundColor": "#334c4f",
|
|
346
346
|
"borderRadius": 999,
|
|
347
347
|
"height": 32,
|
|
348
348
|
"left": 89.6,
|
|
@@ -438,7 +438,7 @@ exports[`AvatarStack renders correctly with custom props 1`] = `
|
|
|
438
438
|
onStartShouldSetResponder={[Function]}
|
|
439
439
|
style={
|
|
440
440
|
Object {
|
|
441
|
-
"backgroundColor": "#
|
|
441
|
+
"backgroundColor": "#001f23",
|
|
442
442
|
"borderRadius": 999,
|
|
443
443
|
"height": 40,
|
|
444
444
|
"left": 0,
|
|
@@ -515,7 +515,7 @@ exports[`AvatarStack renders correctly with custom props 1`] = `
|
|
|
515
515
|
onStartShouldSetResponder={[Function]}
|
|
516
516
|
style={
|
|
517
517
|
Object {
|
|
518
|
-
"backgroundColor": "#
|
|
518
|
+
"backgroundColor": "#0d2a2e",
|
|
519
519
|
"borderRadius": 999,
|
|
520
520
|
"height": 40,
|
|
521
521
|
"left": 28,
|
|
@@ -592,7 +592,7 @@ exports[`AvatarStack renders correctly with custom props 1`] = `
|
|
|
592
592
|
onStartShouldSetResponder={[Function]}
|
|
593
593
|
style={
|
|
594
594
|
Object {
|
|
595
|
-
"backgroundColor": "#
|
|
595
|
+
"backgroundColor": "#193539",
|
|
596
596
|
"borderRadius": 999,
|
|
597
597
|
"height": 40,
|
|
598
598
|
"left": 56,
|
|
@@ -669,7 +669,7 @@ exports[`AvatarStack renders correctly with custom props 1`] = `
|
|
|
669
669
|
onStartShouldSetResponder={[Function]}
|
|
670
670
|
style={
|
|
671
671
|
Object {
|
|
672
|
-
"backgroundColor": "#
|
|
672
|
+
"backgroundColor": "#264144",
|
|
673
673
|
"borderRadius": 999,
|
|
674
674
|
"height": 40,
|
|
675
675
|
"left": 84,
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Dimensions, View, ViewStyle } from 'react-native';
|
|
3
|
+
import { ModalHandler, showFABModal } from './ModalPresenter';
|
|
4
|
+
|
|
5
|
+
const wrapperStyle: ViewStyle = {
|
|
6
|
+
width: Dimensions.get('window').width,
|
|
7
|
+
height: Dimensions.get('window').height,
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export interface ModalProps {
|
|
11
|
+
/**
|
|
12
|
+
* Content of the modal.
|
|
13
|
+
*/
|
|
14
|
+
children: React.ReactElement;
|
|
15
|
+
/**
|
|
16
|
+
* Visibility of the modal
|
|
17
|
+
*/
|
|
18
|
+
visible?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Callback when the modal is shown.
|
|
21
|
+
*/
|
|
22
|
+
onShow?: () => void;
|
|
23
|
+
/**
|
|
24
|
+
* TestID of the modal.
|
|
25
|
+
*/
|
|
26
|
+
testID?: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const fABModal = ({ children, onShow, testID, visible = true }: ModalProps) => {
|
|
30
|
+
const [modalHandler, setModalHandler] = React.useState<ModalHandler>();
|
|
31
|
+
|
|
32
|
+
const getModalContent = React.useCallback(
|
|
33
|
+
() => (
|
|
34
|
+
<View pointerEvents="box-none" style={wrapperStyle} testID={testID}>
|
|
35
|
+
{children}
|
|
36
|
+
</View>
|
|
37
|
+
),
|
|
38
|
+
[visible, children, onShow, testID]
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
React.useEffect(() => {
|
|
42
|
+
if (visible) {
|
|
43
|
+
// Modal does not exist, create a new one
|
|
44
|
+
if (!modalHandler) {
|
|
45
|
+
const newModalHandler = showFABModal(getModalContent());
|
|
46
|
+
setModalHandler(newModalHandler);
|
|
47
|
+
|
|
48
|
+
onShow?.();
|
|
49
|
+
}
|
|
50
|
+
// Modal already exists, update it
|
|
51
|
+
else {
|
|
52
|
+
modalHandler.update(getModalContent());
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
modalHandler?.dismiss();
|
|
56
|
+
setModalHandler(undefined);
|
|
57
|
+
}
|
|
58
|
+
}, [getModalContent]);
|
|
59
|
+
|
|
60
|
+
return null;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
export default fABModal;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleProp, View, ViewStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
type ModalContentWrapperProps = {
|
|
5
|
+
children: React.ReactElement;
|
|
6
|
+
visible?: boolean;
|
|
7
|
+
testID?: string;
|
|
8
|
+
style?: StyleProp<ViewStyle>;
|
|
9
|
+
animated?: boolean;
|
|
10
|
+
pointerEvents: 'box-none' | 'none' | 'box-only' | 'auto';
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type ModalContentWrapperHandler = {
|
|
14
|
+
hide: (callback?: () => void) => void;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const FABModalContentWrapper = ({
|
|
18
|
+
children,
|
|
19
|
+
testID,
|
|
20
|
+
pointerEvents,
|
|
21
|
+
}: ModalContentWrapperProps) => {
|
|
22
|
+
return (
|
|
23
|
+
<View testID={testID} pointerEvents={pointerEvents}>
|
|
24
|
+
{children}
|
|
25
|
+
</View>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
FABModalContentWrapper.displayName = 'FABModalContentWrapper';
|
|
30
|
+
|
|
31
|
+
export default FABModalContentWrapper;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import React, { forwardRef, useRef } from 'react';
|
|
2
|
+
import { Animated, StyleSheet, ViewProps } from 'react-native';
|
|
3
|
+
import RootSiblings from 'react-native-root-siblings';
|
|
4
|
+
import Box from '../../../Box';
|
|
5
|
+
|
|
6
|
+
export type ModalPresenterHandles = {
|
|
7
|
+
animatedOut: (completion?: () => void) => void;
|
|
8
|
+
};
|
|
9
|
+
export type FABModalDismissFunc = (onDismiss?: () => void) => void;
|
|
10
|
+
export type FABModalUpdateFunc = (content: React.ReactNode) => void;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Modal handler is returned by `showModal` function.
|
|
14
|
+
*/
|
|
15
|
+
export type FABModalHandler = {
|
|
16
|
+
/**
|
|
17
|
+
* Same `dismiss` function as in `ModalContentProps`.
|
|
18
|
+
*/
|
|
19
|
+
dismiss: FABModalDismissFunc;
|
|
20
|
+
/**
|
|
21
|
+
* Same `update` function as in `ModalContentProps`.
|
|
22
|
+
*/
|
|
23
|
+
update: FABModalUpdateFunc;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const FABModalPresenter = forwardRef<ModalPresenterHandles, ViewProps>(
|
|
27
|
+
({ style, children, ...props }, ref) => {
|
|
28
|
+
const animatedOpacity = useRef(new Animated.Value(0));
|
|
29
|
+
|
|
30
|
+
React.useEffect(() => {
|
|
31
|
+
Animated.spring(animatedOpacity.current, {
|
|
32
|
+
toValue: 1,
|
|
33
|
+
useNativeDriver: true,
|
|
34
|
+
}).start();
|
|
35
|
+
}, []);
|
|
36
|
+
|
|
37
|
+
React.useImperativeHandle(ref, () => ({
|
|
38
|
+
animatedOut: (completion?: () => void) => {
|
|
39
|
+
Animated.spring(animatedOpacity.current, {
|
|
40
|
+
toValue: 0,
|
|
41
|
+
useNativeDriver: true,
|
|
42
|
+
}).start(() => {
|
|
43
|
+
completion?.();
|
|
44
|
+
});
|
|
45
|
+
},
|
|
46
|
+
}));
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<Box style={StyleSheet.absoluteFill} pointerEvents="box-none">
|
|
50
|
+
<Animated.View
|
|
51
|
+
style={[
|
|
52
|
+
{
|
|
53
|
+
width: '100%',
|
|
54
|
+
height: '100%',
|
|
55
|
+
justifyContent: 'center',
|
|
56
|
+
alignItems: 'center',
|
|
57
|
+
opacity: animatedOpacity.current,
|
|
58
|
+
},
|
|
59
|
+
style,
|
|
60
|
+
]}
|
|
61
|
+
{...props}
|
|
62
|
+
pointerEvents="box-none"
|
|
63
|
+
>
|
|
64
|
+
{children}
|
|
65
|
+
</Animated.View>
|
|
66
|
+
</Box>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Present a modal on screen immediately.
|
|
73
|
+
*
|
|
74
|
+
* The new presented modal will be on top of existing modals if there are any.
|
|
75
|
+
*
|
|
76
|
+
* @param Content A component to be presented as a modal on screen.
|
|
77
|
+
* This component will be centered horizontally and vertically on screen with
|
|
78
|
+
* a semitransparent black overlay underneath.
|
|
79
|
+
* @param contentProps Props for this modal component.
|
|
80
|
+
* @returns A `ModalHandler` you can use to dismiss the modal.
|
|
81
|
+
*/
|
|
82
|
+
|
|
83
|
+
export const showFABModal = (content: React.ReactNode): FABModalHandler => {
|
|
84
|
+
let ref: ModalPresenterHandles | null = null;
|
|
85
|
+
let rootSiblings: RootSiblings | null = null;
|
|
86
|
+
|
|
87
|
+
const dismiss: FABModalDismissFunc = (onDismiss) => {
|
|
88
|
+
if (rootSiblings) {
|
|
89
|
+
const cleanup = () => {
|
|
90
|
+
rootSiblings?.destroy();
|
|
91
|
+
rootSiblings = null;
|
|
92
|
+
ref = null;
|
|
93
|
+
onDismiss?.();
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
if (ref) {
|
|
97
|
+
ref.animatedOut(cleanup);
|
|
98
|
+
} else {
|
|
99
|
+
cleanup();
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
const update: FABModalUpdateFunc = (newContent) => {
|
|
105
|
+
rootSiblings?.update(
|
|
106
|
+
<FABModalPresenter
|
|
107
|
+
ref={(_ref) => {
|
|
108
|
+
ref = _ref;
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
{newContent}
|
|
112
|
+
</FABModalPresenter>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
rootSiblings = new RootSiblings(
|
|
117
|
+
(
|
|
118
|
+
<FABModalPresenter
|
|
119
|
+
ref={(_ref) => {
|
|
120
|
+
ref = _ref;
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
{content}
|
|
124
|
+
</FABModalPresenter>
|
|
125
|
+
)
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
return { dismiss, update };
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
FABModalPresenter.displayName = 'FABModalPresenter';
|
|
132
|
+
|
|
133
|
+
export default FABModalPresenter;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FABModalDismissFunc,
|
|
3
|
+
FABModalHandler,
|
|
4
|
+
showFABModal,
|
|
5
|
+
ModalPresenterHandles,
|
|
6
|
+
} from './ModalPresenter';
|
|
7
|
+
|
|
8
|
+
export type {
|
|
9
|
+
FABModalDismissFunc as ModalDismissFunc,
|
|
10
|
+
FABModalHandler as ModalHandler,
|
|
11
|
+
ModalPresenterHandles,
|
|
12
|
+
};
|
|
13
|
+
export { showFABModal };
|
|
@@ -764,7 +764,7 @@ exports[`ActionGroup has active true 1`] = `
|
|
|
764
764
|
"backgroundColor": "#000000",
|
|
765
765
|
"bottom": 0,
|
|
766
766
|
"left": 0,
|
|
767
|
-
"opacity": 0.
|
|
767
|
+
"opacity": 0.25,
|
|
768
768
|
"position": "absolute",
|
|
769
769
|
"right": 0,
|
|
770
770
|
"top": 0,
|
|
@@ -1373,7 +1373,7 @@ exports[`ActionGroup has active true 1`] = `
|
|
|
1373
1373
|
Object {
|
|
1374
1374
|
"alignItems": "center",
|
|
1375
1375
|
"alignSelf": "flex-start",
|
|
1376
|
-
"backgroundColor": "#
|
|
1376
|
+
"backgroundColor": "#664780",
|
|
1377
1377
|
"borderRadius": 999,
|
|
1378
1378
|
"elevation": 2,
|
|
1379
1379
|
"flexDirection": "row",
|
|
@@ -14,6 +14,7 @@ import {
|
|
|
14
14
|
|
|
15
15
|
import Box from '../../Box';
|
|
16
16
|
import { FABHandles } from '../FAB';
|
|
17
|
+
import FABModal from './FABModal';
|
|
17
18
|
|
|
18
19
|
export type ActionGroupHandles = {
|
|
19
20
|
showFAB: () => void;
|
|
@@ -31,7 +32,6 @@ export interface ActionGroupProps {
|
|
|
31
32
|
* This function is called on pressing the FAB button.
|
|
32
33
|
* */
|
|
33
34
|
onPress?: () => void;
|
|
34
|
-
|
|
35
35
|
/**
|
|
36
36
|
* Specify if the FAB button is in active state and the action group is shown.
|
|
37
37
|
* */
|
|
@@ -114,7 +114,7 @@ const ActionGroup = forwardRef<ActionGroupHandles, ActionGroupProps>(
|
|
|
114
114
|
const interpolatedBackdropOpacityAnimation =
|
|
115
115
|
tranlateXAnimation.current.interpolate({
|
|
116
116
|
inputRange: [0, 1],
|
|
117
|
-
outputRange: [0, 0.
|
|
117
|
+
outputRange: [0, 0.25],
|
|
118
118
|
});
|
|
119
119
|
|
|
120
120
|
const interpolatedActionGroupOpacityAnimation =
|
|
@@ -124,51 +124,53 @@ const ActionGroup = forwardRef<ActionGroupHandles, ActionGroupProps>(
|
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
return (
|
|
127
|
-
<
|
|
128
|
-
<
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
{
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
127
|
+
<FABModal>
|
|
128
|
+
<StyledContainer testID={testID} pointerEvents="box-none" style={style}>
|
|
129
|
+
<StyledBackdrop
|
|
130
|
+
pointerEvents={active ? 'auto' : 'box-none'}
|
|
131
|
+
testID="back-drop"
|
|
132
|
+
style={{ opacity: interpolatedBackdropOpacityAnimation }}
|
|
133
|
+
/>
|
|
134
|
+
<StyledActionGroupContainer
|
|
135
|
+
pointerEvents={active ? 'auto' : 'none'}
|
|
136
|
+
testID="action-group"
|
|
137
|
+
style={{
|
|
138
|
+
opacity: interpolatedActionGroupOpacityAnimation,
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
{!!headerTitle && (
|
|
142
|
+
<Animated.View
|
|
143
|
+
style={{ transform: [{ translateY: titleTranslateY }] }}
|
|
144
|
+
>
|
|
145
|
+
<StyledHeaderText testID="header-text" level="h4">
|
|
146
|
+
{headerTitle}
|
|
147
|
+
</StyledHeaderText>
|
|
148
|
+
</Animated.View>
|
|
149
|
+
)}
|
|
150
|
+
|
|
151
|
+
<Box style={[style, { paddingBottom: 0 }]}>
|
|
152
|
+
{items?.map((itemProp, index) => (
|
|
153
|
+
<ActionItem
|
|
154
|
+
key={itemProp.key || `${itemProp.icon}_${itemProp.title}`}
|
|
155
|
+
{...itemProp}
|
|
156
|
+
index={active ? index : items.length - index}
|
|
157
|
+
active={active}
|
|
158
|
+
/>
|
|
159
|
+
))}
|
|
160
|
+
</Box>
|
|
161
|
+
</StyledActionGroupContainer>
|
|
162
|
+
|
|
163
|
+
<StyledFAB
|
|
164
|
+
testID="fab"
|
|
165
|
+
icon={fabIcon}
|
|
166
|
+
onPress={onPress}
|
|
167
|
+
animated
|
|
168
|
+
active={active}
|
|
169
|
+
title={fabTitle}
|
|
170
|
+
ref={fabRef}
|
|
171
|
+
/>
|
|
172
|
+
</StyledContainer>
|
|
173
|
+
</FABModal>
|
|
172
174
|
);
|
|
173
175
|
}
|
|
174
176
|
);
|
|
@@ -6,22 +6,26 @@ import Icon from '../Icon';
|
|
|
6
6
|
import Typography from '../Typography';
|
|
7
7
|
import Box from '../Box';
|
|
8
8
|
|
|
9
|
-
const StyledFAB = styled(TouchableHighlight)<
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
9
|
+
const StyledFAB = styled(TouchableHighlight)<
|
|
10
|
+
TouchableHighlightProps & {
|
|
11
|
+
themeActive?: boolean;
|
|
12
|
+
}
|
|
13
|
+
>(({ theme, themeActive }) => ({
|
|
14
|
+
backgroundColor: themeActive
|
|
15
|
+
? theme.__hd__.fab.colors.buttonActiveBackground
|
|
16
|
+
: theme.__hd__.fab.colors.buttonBackground,
|
|
17
|
+
borderRadius: theme.radii.rounded,
|
|
18
|
+
alignItems: 'center',
|
|
19
|
+
justifyContent: 'center',
|
|
20
|
+
alignSelf: 'flex-start',
|
|
21
|
+
padding: theme.__hd__.fab.space.containerPadding,
|
|
22
|
+
flexDirection: 'row',
|
|
23
|
+
elevation: theme.__hd__.fab.shadows.elevation,
|
|
24
|
+
shadowColor: theme.__hd__.fab.colors.shadow,
|
|
25
|
+
shadowOffset: theme.__hd__.fab.shadows.offset,
|
|
26
|
+
shadowRadius: theme.__hd__.fab.shadows.radius,
|
|
27
|
+
shadowOpacity: theme.__hd__.fab.shadows.opacity,
|
|
28
|
+
}));
|
|
25
29
|
|
|
26
30
|
const StyledFABIcon = styled(Icon)<IconProps>(({ theme }) => ({
|
|
27
31
|
color: theme.__hd__.fab.colors.icon,
|
|
@@ -6,7 +6,17 @@ import { StyledFAB, StyledFABIcon } from '../StyledFAB';
|
|
|
6
6
|
describe('StyledFAB', () => {
|
|
7
7
|
it('renders correctly', () => {
|
|
8
8
|
const { toJSON } = renderWithTheme(
|
|
9
|
-
<StyledFAB>
|
|
9
|
+
<StyledFAB themeActive={false}>
|
|
10
|
+
<Typography.Body variant="small"> button </Typography.Body>
|
|
11
|
+
</StyledFAB>
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
expect(toJSON()).toMatchSnapshot();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders correctly', () => {
|
|
18
|
+
const { toJSON } = renderWithTheme(
|
|
19
|
+
<StyledFAB themeActive>
|
|
10
20
|
<Typography.Body variant="small"> button </Typography.Body>
|
|
11
21
|
</StyledFAB>
|
|
12
22
|
);
|
|
@@ -57,6 +57,63 @@ exports[`StyledFAB renders correctly 1`] = `
|
|
|
57
57
|
</View>
|
|
58
58
|
`;
|
|
59
59
|
|
|
60
|
+
exports[`StyledFAB renders correctly 2`] = `
|
|
61
|
+
<View
|
|
62
|
+
accessible={true}
|
|
63
|
+
focusable={false}
|
|
64
|
+
onClick={[Function]}
|
|
65
|
+
onResponderGrant={[Function]}
|
|
66
|
+
onResponderMove={[Function]}
|
|
67
|
+
onResponderRelease={[Function]}
|
|
68
|
+
onResponderTerminate={[Function]}
|
|
69
|
+
onResponderTerminationRequest={[Function]}
|
|
70
|
+
onStartShouldSetResponder={[Function]}
|
|
71
|
+
style={
|
|
72
|
+
Array [
|
|
73
|
+
Object {
|
|
74
|
+
"alignItems": "center",
|
|
75
|
+
"alignSelf": "flex-start",
|
|
76
|
+
"backgroundColor": "#664780",
|
|
77
|
+
"borderRadius": 999,
|
|
78
|
+
"elevation": 2,
|
|
79
|
+
"flexDirection": "row",
|
|
80
|
+
"justifyContent": "center",
|
|
81
|
+
"padding": 20,
|
|
82
|
+
"shadowColor": "#001f23",
|
|
83
|
+
"shadowOffset": Object {
|
|
84
|
+
"height": 2,
|
|
85
|
+
"width": 0,
|
|
86
|
+
},
|
|
87
|
+
"shadowOpacity": 0.12,
|
|
88
|
+
"shadowRadius": 8,
|
|
89
|
+
},
|
|
90
|
+
undefined,
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
>
|
|
94
|
+
<Text
|
|
95
|
+
allowFontScaling={false}
|
|
96
|
+
style={
|
|
97
|
+
Array [
|
|
98
|
+
Object {
|
|
99
|
+
"color": "#001f23",
|
|
100
|
+
"fontFamily": "BeVietnamPro-Regular",
|
|
101
|
+
"fontSize": 14,
|
|
102
|
+
"letterSpacing": 0.48,
|
|
103
|
+
"lineHeight": 22,
|
|
104
|
+
},
|
|
105
|
+
undefined,
|
|
106
|
+
]
|
|
107
|
+
}
|
|
108
|
+
themeIntent="body"
|
|
109
|
+
themeTypeface="neutral"
|
|
110
|
+
themeVariant="small"
|
|
111
|
+
>
|
|
112
|
+
button
|
|
113
|
+
</Text>
|
|
114
|
+
</View>
|
|
115
|
+
`;
|
|
116
|
+
|
|
60
117
|
exports[`StyledFABIcon renders correctly 1`] = `
|
|
61
118
|
<HeroIcon
|
|
62
119
|
name="add"
|