@hero-design/rn 7.23.0 → 7.24.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 +2 -2
- package/assets/fonts/hero-icons.ttf +0 -0
- package/es/index.js +857 -8825
- package/lib/assets/fonts/hero-icons.ttf +0 -0
- package/lib/index.js +858 -8824
- package/package.json +6 -4
- package/rollup.config.js +1 -0
- package/src/components/DatePicker/__tests__/__snapshots__/DatePickerAndroid.spec.tsx.snap +1 -0
- package/src/components/DatePicker/__tests__/__snapshots__/DatePickerIOS.spec.tsx.snap +1 -0
- package/src/components/Empty/index.tsx +1 -2
- package/src/components/Icon/HeroIcon/fonts/hero-icons.ttf +0 -0
- package/src/components/Icon/HeroIcon/glyphMap.json +1 -0
- package/src/components/Icon/HeroIcon/index.tsx +3 -7
- package/src/components/Icon/IconList.ts +8 -5
- package/src/components/Icon/index.tsx +1 -0
- package/src/components/RichTextEditor/RichTextEditor.tsx +1 -4
- package/src/components/RichTextEditor/__tests__/__snapshots__/RichTextEditor.spec.tsx.snap +2 -0
- package/src/components/Select/MultiSelect/__tests__/__snapshots__/OptionList.spec.tsx.snap +8 -4
- package/src/components/Select/MultiSelect/__tests__/__snapshots__/index.spec.tsx.snap +5 -0
- package/src/components/Select/SingleSelect/__tests__/__snapshots__/OptionList.spec.tsx.snap +8 -4
- package/src/components/Select/SingleSelect/__tests__/__snapshots__/index.spec.tsx.snap +5 -0
- package/src/components/Spinner/AnimatedSpinner.tsx +22 -7
- package/src/components/Spinner/StyledSpinner.tsx +16 -11
- package/src/components/Spinner/__tests__/AnimatedSpinner.spec.tsx +3 -1
- package/src/components/Spinner/__tests__/StyledSpinner.spec.tsx +42 -31
- package/src/components/Spinner/__tests__/__snapshots__/AnimatedSpinner.spec.tsx.snap +8 -4
- package/src/components/Spinner/__tests__/__snapshots__/StyledSpinner.spec.tsx.snap +532 -72
- package/src/components/Spinner/__tests__/__snapshots__/index.spec.tsx.snap +8 -4
- package/src/components/Spinner/index.tsx +6 -1
- package/src/components/Swipeable/StyledSwipeable.tsx +11 -0
- package/src/components/Swipeable/SwipeableAction.tsx +45 -0
- package/src/components/Swipeable/__tests__/SwipeableAction.spec.tsx +37 -0
- package/src/components/Swipeable/__tests__/__snapshots__/SwipeableAction.spec.tsx.snap +130 -0
- package/src/components/Swipeable/__tests__/__snapshots__/index.spec.tsx.snap +33 -0
- package/src/components/Swipeable/__tests__/index.spec.tsx +34 -0
- package/src/components/Swipeable/index.tsx +148 -0
- package/src/components/TextInput/StyledTextInput.tsx +6 -12
- package/src/components/TextInput/__tests__/StyledTextInput.spec.tsx +12 -6
- package/src/components/TextInput/__tests__/__snapshots__/StyledTextInput.spec.tsx.snap +22 -138
- package/src/components/TextInput/__tests__/__snapshots__/index.spec.tsx.snap +13 -0
- package/src/components/TextInput/__tests__/index.spec.tsx +114 -124
- package/src/components/TextInput/index.tsx +7 -6
- package/src/components/TimePicker/__tests__/__snapshots__/TimePickerAndroid.spec.tsx.snap +1 -0
- package/src/components/TimePicker/__tests__/__snapshots__/TimePickerIOS.spec.tsx.snap +1 -0
- package/src/index.ts +4 -0
- package/src/theme/__tests__/__snapshots__/index.spec.ts.snap +11 -6
- package/src/theme/components/spinner.ts +4 -1
- package/src/theme/components/swipeable.ts +13 -0
- package/src/theme/components/textInput.ts +0 -5
- package/src/theme/getTheme.ts +3 -0
- package/src/theme/global/colors/jobs.ts +0 -1
- package/src/theme/global/colors/work.ts +0 -2
- package/src/types.ts +2 -0
- package/testUtils/setup.tsx +13 -0
- package/types/components/Empty/index.d.ts +1 -2
- package/types/components/Icon/IconList.d.ts +1 -1
- package/types/components/Icon/index.d.ts +4 -1
- package/types/components/Icon/utils.d.ts +1 -1
- package/types/components/Spinner/AnimatedSpinner.d.ts +2 -1
- package/types/components/Spinner/StyledSpinner.d.ts +1 -0
- package/types/components/Spinner/index.d.ts +5 -1
- package/types/components/Swipeable/StyledSwipeable.d.ts +10 -0
- package/types/components/Swipeable/SwipeableAction.d.ts +27 -0
- package/types/components/Swipeable/index.d.ts +41 -0
- package/types/components/TextInput/StyledTextInput.d.ts +2 -1
- package/types/components/TextInput/index.d.ts +1 -1
- package/types/index.d.ts +3 -2
- package/types/theme/components/spinner.d.ts +4 -1
- package/types/theme/components/swipeable.d.ts +9 -0
- package/types/theme/components/textInput.d.ts +0 -5
- package/types/theme/getTheme.d.ts +2 -0
- package/types/types.d.ts +2 -1
- package/src/components/Icon/HeroIcon/selection.json +0 -7029
|
@@ -59,12 +59,13 @@ exports[`Spinner renders correctly 1`] = `
|
|
|
59
59
|
"backgroundColor": "#001f23",
|
|
60
60
|
"borderRadius": 999,
|
|
61
61
|
"height": 16,
|
|
62
|
-
"opacity":
|
|
62
|
+
"opacity": 0.9,
|
|
63
63
|
"width": 16,
|
|
64
64
|
},
|
|
65
65
|
Object {},
|
|
66
66
|
]
|
|
67
67
|
}
|
|
68
|
+
themeIntent="primary"
|
|
68
69
|
themePosition="topLeft"
|
|
69
70
|
themeSize="medium"
|
|
70
71
|
/>
|
|
@@ -78,12 +79,13 @@ exports[`Spinner renders correctly 1`] = `
|
|
|
78
79
|
"borderRadius": 999,
|
|
79
80
|
"height": 16,
|
|
80
81
|
"marginLeft": 8,
|
|
81
|
-
"opacity": 0.
|
|
82
|
+
"opacity": 0.675,
|
|
82
83
|
"width": 16,
|
|
83
84
|
},
|
|
84
85
|
Object {},
|
|
85
86
|
]
|
|
86
87
|
}
|
|
88
|
+
themeIntent="primary"
|
|
87
89
|
themePosition="topRight"
|
|
88
90
|
themeSize="medium"
|
|
89
91
|
/>
|
|
@@ -112,12 +114,13 @@ exports[`Spinner renders correctly 1`] = `
|
|
|
112
114
|
"backgroundColor": "#001f23",
|
|
113
115
|
"borderRadius": 999,
|
|
114
116
|
"height": 16,
|
|
115
|
-
"opacity": 0.
|
|
117
|
+
"opacity": 0.45,
|
|
116
118
|
"width": 16,
|
|
117
119
|
},
|
|
118
120
|
Object {},
|
|
119
121
|
]
|
|
120
122
|
}
|
|
123
|
+
themeIntent="primary"
|
|
121
124
|
themePosition="bottomLeft"
|
|
122
125
|
themeSize="medium"
|
|
123
126
|
/>
|
|
@@ -131,12 +134,13 @@ exports[`Spinner renders correctly 1`] = `
|
|
|
131
134
|
"borderRadius": 999,
|
|
132
135
|
"height": 16,
|
|
133
136
|
"marginLeft": 8,
|
|
134
|
-
"opacity": 0.
|
|
137
|
+
"opacity": 0.225,
|
|
135
138
|
"width": 16,
|
|
136
139
|
},
|
|
137
140
|
Object {},
|
|
138
141
|
]
|
|
139
142
|
}
|
|
143
|
+
themeIntent="primary"
|
|
140
144
|
themePosition="bottomRight"
|
|
141
145
|
themeSize="medium"
|
|
142
146
|
/>
|
|
@@ -9,6 +9,10 @@ interface SpinnerProps extends ViewProps {
|
|
|
9
9
|
* Size of Spinner.
|
|
10
10
|
*/
|
|
11
11
|
size?: 'small' | 'medium';
|
|
12
|
+
/**
|
|
13
|
+
* Spinner's variant.
|
|
14
|
+
*/
|
|
15
|
+
intent?: 'primary' | 'inverted';
|
|
12
16
|
/**
|
|
13
17
|
* Testing id of the component.
|
|
14
18
|
*/
|
|
@@ -18,11 +22,12 @@ interface SpinnerProps extends ViewProps {
|
|
|
18
22
|
const Spinner = ({
|
|
19
23
|
testID,
|
|
20
24
|
size = 'medium',
|
|
25
|
+
intent = 'primary',
|
|
21
26
|
...nativeProps
|
|
22
27
|
}: SpinnerProps): ReactElement => (
|
|
23
28
|
<StyledView {...nativeProps}>
|
|
24
29
|
<StyledSpinnerContainer testID={testID}>
|
|
25
|
-
<AnimatedSpinner size={size} />
|
|
30
|
+
<AnimatedSpinner size={size} intent={intent} />
|
|
26
31
|
</StyledSpinnerContainer>
|
|
27
32
|
</StyledView>
|
|
28
33
|
);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import styled from '@emotion/native';
|
|
2
|
+
import { TouchableOpacity } from 'react-native';
|
|
3
|
+
|
|
4
|
+
export type ActionIntent = 'primary' | 'success' | 'danger';
|
|
5
|
+
|
|
6
|
+
export const StyledRectButton = styled(TouchableOpacity)<{
|
|
7
|
+
themeIntent: ActionIntent;
|
|
8
|
+
}>(({ theme, themeIntent }) => ({
|
|
9
|
+
flex: 1,
|
|
10
|
+
backgroundColor: theme.__hd__.swipeable.colors[themeIntent],
|
|
11
|
+
}));
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import { ActionIntent, StyledRectButton } from './StyledSwipeable';
|
|
4
|
+
|
|
5
|
+
export interface SwipeableActionProps {
|
|
6
|
+
/**
|
|
7
|
+
* Visual intent color applied to action.
|
|
8
|
+
*/
|
|
9
|
+
intent?: ActionIntent;
|
|
10
|
+
/**
|
|
11
|
+
* Callback when the action button is pressed.
|
|
12
|
+
*/
|
|
13
|
+
onPress?: () => void;
|
|
14
|
+
/**
|
|
15
|
+
* Action button's content
|
|
16
|
+
*/
|
|
17
|
+
children?: ReactNode;
|
|
18
|
+
/**
|
|
19
|
+
* Additional style.
|
|
20
|
+
*/
|
|
21
|
+
style?: StyleProp<ViewStyle>;
|
|
22
|
+
/**
|
|
23
|
+
* Testing id of the component.
|
|
24
|
+
*/
|
|
25
|
+
testID?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const SwipeableAction = ({
|
|
29
|
+
intent = 'primary',
|
|
30
|
+
onPress,
|
|
31
|
+
style,
|
|
32
|
+
children,
|
|
33
|
+
testID,
|
|
34
|
+
}: SwipeableActionProps) => (
|
|
35
|
+
<StyledRectButton
|
|
36
|
+
onPress={onPress}
|
|
37
|
+
themeIntent={intent}
|
|
38
|
+
style={style}
|
|
39
|
+
testID={testID}
|
|
40
|
+
>
|
|
41
|
+
{children}
|
|
42
|
+
</StyledRectButton>
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
export default SwipeableAction;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { fireEvent } from '@testing-library/react-native';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import renderWithTheme from '../../../testHelpers/renderWithTheme';
|
|
4
|
+
import Typography from '../../Typography';
|
|
5
|
+
import SwipeableAction from '../SwipeableAction';
|
|
6
|
+
|
|
7
|
+
describe('rendering', () => {
|
|
8
|
+
it.each`
|
|
9
|
+
intent
|
|
10
|
+
${'primary'}
|
|
11
|
+
${'success'}
|
|
12
|
+
${'danger'}
|
|
13
|
+
`('renders correctly when intent is $intent', ({ intent }) => {
|
|
14
|
+
const { toJSON, getByText } = renderWithTheme(
|
|
15
|
+
<SwipeableAction intent={intent}>
|
|
16
|
+
<Typography.Text>Action title</Typography.Text>
|
|
17
|
+
</SwipeableAction>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
expect(getByText('Action title')).toBeDefined();
|
|
21
|
+
expect(toJSON()).toMatchSnapshot();
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('behavior', () => {
|
|
26
|
+
it('calls onPress', () => {
|
|
27
|
+
const onPress = jest.fn();
|
|
28
|
+
const { getByText } = renderWithTheme(
|
|
29
|
+
<SwipeableAction onPress={onPress}>
|
|
30
|
+
<Typography.Text>Action title</Typography.Text>
|
|
31
|
+
</SwipeableAction>
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
fireEvent.press(getByText('Action title'));
|
|
35
|
+
expect(onPress).toBeCalledTimes(1);
|
|
36
|
+
});
|
|
37
|
+
});
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`rendering renders correctly when intent is danger 1`] = `
|
|
4
|
+
<View
|
|
5
|
+
accessible={true}
|
|
6
|
+
collapsable={false}
|
|
7
|
+
focusable={false}
|
|
8
|
+
nativeID="animatedComponent"
|
|
9
|
+
onClick={[Function]}
|
|
10
|
+
onResponderGrant={[Function]}
|
|
11
|
+
onResponderMove={[Function]}
|
|
12
|
+
onResponderRelease={[Function]}
|
|
13
|
+
onResponderTerminate={[Function]}
|
|
14
|
+
onResponderTerminationRequest={[Function]}
|
|
15
|
+
onStartShouldSetResponder={[Function]}
|
|
16
|
+
style={
|
|
17
|
+
Object {
|
|
18
|
+
"backgroundColor": "#f46363",
|
|
19
|
+
"flex": 1,
|
|
20
|
+
"opacity": 1,
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
>
|
|
24
|
+
<Text
|
|
25
|
+
style={
|
|
26
|
+
Array [
|
|
27
|
+
Object {
|
|
28
|
+
"color": "#001f23",
|
|
29
|
+
"fontFamily": "BeVietnamPro-Regular",
|
|
30
|
+
"fontSize": 14,
|
|
31
|
+
"letterSpacing": 0.42,
|
|
32
|
+
"lineHeight": 22,
|
|
33
|
+
},
|
|
34
|
+
undefined,
|
|
35
|
+
]
|
|
36
|
+
}
|
|
37
|
+
themeFontSize="medium"
|
|
38
|
+
themeFontWeight="regular"
|
|
39
|
+
themeIntent="body"
|
|
40
|
+
>
|
|
41
|
+
Action title
|
|
42
|
+
</Text>
|
|
43
|
+
</View>
|
|
44
|
+
`;
|
|
45
|
+
|
|
46
|
+
exports[`rendering renders correctly when intent is primary 1`] = `
|
|
47
|
+
<View
|
|
48
|
+
accessible={true}
|
|
49
|
+
collapsable={false}
|
|
50
|
+
focusable={false}
|
|
51
|
+
nativeID="animatedComponent"
|
|
52
|
+
onClick={[Function]}
|
|
53
|
+
onResponderGrant={[Function]}
|
|
54
|
+
onResponderMove={[Function]}
|
|
55
|
+
onResponderRelease={[Function]}
|
|
56
|
+
onResponderTerminate={[Function]}
|
|
57
|
+
onResponderTerminationRequest={[Function]}
|
|
58
|
+
onStartShouldSetResponder={[Function]}
|
|
59
|
+
style={
|
|
60
|
+
Object {
|
|
61
|
+
"backgroundColor": "#001f23",
|
|
62
|
+
"flex": 1,
|
|
63
|
+
"opacity": 1,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
>
|
|
67
|
+
<Text
|
|
68
|
+
style={
|
|
69
|
+
Array [
|
|
70
|
+
Object {
|
|
71
|
+
"color": "#001f23",
|
|
72
|
+
"fontFamily": "BeVietnamPro-Regular",
|
|
73
|
+
"fontSize": 14,
|
|
74
|
+
"letterSpacing": 0.42,
|
|
75
|
+
"lineHeight": 22,
|
|
76
|
+
},
|
|
77
|
+
undefined,
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
themeFontSize="medium"
|
|
81
|
+
themeFontWeight="regular"
|
|
82
|
+
themeIntent="body"
|
|
83
|
+
>
|
|
84
|
+
Action title
|
|
85
|
+
</Text>
|
|
86
|
+
</View>
|
|
87
|
+
`;
|
|
88
|
+
|
|
89
|
+
exports[`rendering renders correctly when intent is success 1`] = `
|
|
90
|
+
<View
|
|
91
|
+
accessible={true}
|
|
92
|
+
collapsable={false}
|
|
93
|
+
focusable={false}
|
|
94
|
+
nativeID="animatedComponent"
|
|
95
|
+
onClick={[Function]}
|
|
96
|
+
onResponderGrant={[Function]}
|
|
97
|
+
onResponderMove={[Function]}
|
|
98
|
+
onResponderRelease={[Function]}
|
|
99
|
+
onResponderTerminate={[Function]}
|
|
100
|
+
onResponderTerminationRequest={[Function]}
|
|
101
|
+
onStartShouldSetResponder={[Function]}
|
|
102
|
+
style={
|
|
103
|
+
Object {
|
|
104
|
+
"backgroundColor": "#5ace7d",
|
|
105
|
+
"flex": 1,
|
|
106
|
+
"opacity": 1,
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
>
|
|
110
|
+
<Text
|
|
111
|
+
style={
|
|
112
|
+
Array [
|
|
113
|
+
Object {
|
|
114
|
+
"color": "#001f23",
|
|
115
|
+
"fontFamily": "BeVietnamPro-Regular",
|
|
116
|
+
"fontSize": 14,
|
|
117
|
+
"letterSpacing": 0.42,
|
|
118
|
+
"lineHeight": 22,
|
|
119
|
+
},
|
|
120
|
+
undefined,
|
|
121
|
+
]
|
|
122
|
+
}
|
|
123
|
+
themeFontSize="medium"
|
|
124
|
+
themeFontWeight="regular"
|
|
125
|
+
themeIntent="body"
|
|
126
|
+
>
|
|
127
|
+
Action title
|
|
128
|
+
</Text>
|
|
129
|
+
</View>
|
|
130
|
+
`;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
+
|
|
3
|
+
exports[`Swipeable renders correctly 1`] = `
|
|
4
|
+
<View>
|
|
5
|
+
<View
|
|
6
|
+
onSwipeableClose={[Function]}
|
|
7
|
+
onSwipeableLeftOpen={[Function]}
|
|
8
|
+
onSwipeableRightOpen={[Function]}
|
|
9
|
+
renderLeftActions={[Function]}
|
|
10
|
+
renderRightActions={[Function]}
|
|
11
|
+
>
|
|
12
|
+
<Text
|
|
13
|
+
style={
|
|
14
|
+
Array [
|
|
15
|
+
Object {
|
|
16
|
+
"color": "#001f23",
|
|
17
|
+
"fontFamily": "BeVietnamPro-Regular",
|
|
18
|
+
"fontSize": 14,
|
|
19
|
+
"letterSpacing": 0.42,
|
|
20
|
+
"lineHeight": 22,
|
|
21
|
+
},
|
|
22
|
+
undefined,
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
themeFontSize="medium"
|
|
26
|
+
themeFontWeight="regular"
|
|
27
|
+
themeIntent="body"
|
|
28
|
+
>
|
|
29
|
+
Swipeable Item
|
|
30
|
+
</Text>
|
|
31
|
+
</View>
|
|
32
|
+
</View>
|
|
33
|
+
`;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import renderWithTheme from '../../../testHelpers/renderWithTheme';
|
|
3
|
+
import Typography from '../../Typography';
|
|
4
|
+
import Swipeable from '..';
|
|
5
|
+
|
|
6
|
+
describe('Swipeable', () => {
|
|
7
|
+
it('renders correctly', () => {
|
|
8
|
+
const { toJSON, getByText } = renderWithTheme(
|
|
9
|
+
<Swipeable
|
|
10
|
+
leftActions={
|
|
11
|
+
<Swipeable.Action intent="primary">
|
|
12
|
+
<Typography.Text intent="inverted">Archived</Typography.Text>
|
|
13
|
+
</Swipeable.Action>
|
|
14
|
+
}
|
|
15
|
+
rightActions={
|
|
16
|
+
<>
|
|
17
|
+
<Swipeable.Action intent="success">
|
|
18
|
+
<Typography.Text>Approve</Typography.Text>
|
|
19
|
+
</Swipeable.Action>
|
|
20
|
+
<Swipeable.Action intent="danger">
|
|
21
|
+
<Typography.Text>Decline</Typography.Text>
|
|
22
|
+
</Swipeable.Action>
|
|
23
|
+
</>
|
|
24
|
+
}
|
|
25
|
+
rightActionsWidth={168}
|
|
26
|
+
>
|
|
27
|
+
<Typography.Text>Swipeable Item</Typography.Text>
|
|
28
|
+
</Swipeable>
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
expect(getByText('Swipeable Item')).toBeDefined();
|
|
32
|
+
expect(toJSON()).toMatchSnapshot();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import React, { ReactNode, useCallback, useEffect, useRef } from 'react';
|
|
2
|
+
import { Animated, useWindowDimensions } from 'react-native';
|
|
3
|
+
import type { SwipeableProps as RnghSwipeableProps } from 'react-native-gesture-handler/Swipeable';
|
|
4
|
+
import {
|
|
5
|
+
Swipeable as RnghSwipeable,
|
|
6
|
+
GestureHandlerRootView,
|
|
7
|
+
RectButton,
|
|
8
|
+
} from 'react-native-gesture-handler';
|
|
9
|
+
import SwipeableAction from './SwipeableAction';
|
|
10
|
+
|
|
11
|
+
type State = 'closed' | 'leftOpen' | 'rightOpen';
|
|
12
|
+
export interface SwipeableProps
|
|
13
|
+
extends Pick<
|
|
14
|
+
RnghSwipeableProps,
|
|
15
|
+
| 'enableTrackpadTwoFingerGesture'
|
|
16
|
+
| 'friction'
|
|
17
|
+
| 'leftThreshold'
|
|
18
|
+
| 'rightThreshold'
|
|
19
|
+
| 'overshootLeft'
|
|
20
|
+
| 'overshootRight'
|
|
21
|
+
| 'overshootFriction'
|
|
22
|
+
| 'useNativeAnimations'
|
|
23
|
+
| 'containerStyle'
|
|
24
|
+
| 'childrenContainerStyle'
|
|
25
|
+
> {
|
|
26
|
+
/**
|
|
27
|
+
* React node that is swipeable.
|
|
28
|
+
*/
|
|
29
|
+
children: ReactNode;
|
|
30
|
+
/**
|
|
31
|
+
* State of the component.
|
|
32
|
+
*/
|
|
33
|
+
state?: 'closed' | 'leftOpen' | 'rightOpen';
|
|
34
|
+
/**
|
|
35
|
+
* Callback when the state of the component changes.
|
|
36
|
+
*/
|
|
37
|
+
onStateChange?: (state: State) => void;
|
|
38
|
+
/**
|
|
39
|
+
* Action panel that is going to be revealed from the left side when user swipes right.
|
|
40
|
+
*/
|
|
41
|
+
leftActions?: ReactNode;
|
|
42
|
+
/**
|
|
43
|
+
* Width of the left action panel.
|
|
44
|
+
* By default, it will take up the whole width of the device.
|
|
45
|
+
*/
|
|
46
|
+
leftActionsWidth?: number;
|
|
47
|
+
/**
|
|
48
|
+
* Action panel that is going to be revealed from the right side when user swipes left.
|
|
49
|
+
*/
|
|
50
|
+
rightActions?: ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* Width of the right action panel.
|
|
53
|
+
* By default, it will take up the whole width of the device.
|
|
54
|
+
*/
|
|
55
|
+
rightActionsWidth?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const renderActions = (
|
|
59
|
+
actions: ReactNode,
|
|
60
|
+
width: number,
|
|
61
|
+
progress: Animated.AnimatedInterpolation,
|
|
62
|
+
direction: 'left' | 'right'
|
|
63
|
+
) => {
|
|
64
|
+
const trans = progress.interpolate({
|
|
65
|
+
inputRange: [0, 1],
|
|
66
|
+
outputRange: direction === 'left' ? [-width, 0] : [width, 0],
|
|
67
|
+
extrapolate: 'clamp',
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<Animated.View
|
|
72
|
+
style={{
|
|
73
|
+
width,
|
|
74
|
+
flexDirection: 'row',
|
|
75
|
+
transform: [{ translateX: trans }],
|
|
76
|
+
}}
|
|
77
|
+
>
|
|
78
|
+
{actions}
|
|
79
|
+
</Animated.View>
|
|
80
|
+
);
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const Swipeable = ({
|
|
84
|
+
children,
|
|
85
|
+
state,
|
|
86
|
+
onStateChange,
|
|
87
|
+
leftActions,
|
|
88
|
+
leftActionsWidth,
|
|
89
|
+
rightActions,
|
|
90
|
+
rightActionsWidth,
|
|
91
|
+
...swipeableProps
|
|
92
|
+
}: SwipeableProps) => {
|
|
93
|
+
const { width } = useWindowDimensions();
|
|
94
|
+
const swipeableRef = useRef<RnghSwipeable>(null);
|
|
95
|
+
|
|
96
|
+
const renderLeftActions = useCallback(
|
|
97
|
+
(progress: Animated.AnimatedInterpolation) =>
|
|
98
|
+
renderActions(leftActions, leftActionsWidth || width, progress, 'left'),
|
|
99
|
+
[leftActions, leftActionsWidth, width]
|
|
100
|
+
);
|
|
101
|
+
const renderRightActions = useCallback(
|
|
102
|
+
(progress: Animated.AnimatedInterpolation) =>
|
|
103
|
+
renderActions(
|
|
104
|
+
rightActions,
|
|
105
|
+
rightActionsWidth || width,
|
|
106
|
+
progress,
|
|
107
|
+
'right'
|
|
108
|
+
),
|
|
109
|
+
[rightActions, rightActionsWidth, width]
|
|
110
|
+
);
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (swipeableRef.current === null) return;
|
|
114
|
+
|
|
115
|
+
switch (state) {
|
|
116
|
+
case 'leftOpen':
|
|
117
|
+
swipeableRef.current.openLeft();
|
|
118
|
+
break;
|
|
119
|
+
case 'rightOpen':
|
|
120
|
+
swipeableRef.current.openRight();
|
|
121
|
+
break;
|
|
122
|
+
case 'closed':
|
|
123
|
+
swipeableRef.current.close();
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
}, [state]);
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<GestureHandlerRootView>
|
|
130
|
+
<RnghSwipeable
|
|
131
|
+
{...swipeableProps}
|
|
132
|
+
ref={swipeableRef}
|
|
133
|
+
{...(leftActions !== undefined && { renderLeftActions })}
|
|
134
|
+
{...(rightActions !== undefined && { renderRightActions })}
|
|
135
|
+
onSwipeableLeftOpen={() => onStateChange?.('leftOpen')}
|
|
136
|
+
onSwipeableRightOpen={() => onStateChange?.('rightOpen')}
|
|
137
|
+
onSwipeableClose={() => onStateChange?.('closed')}
|
|
138
|
+
>
|
|
139
|
+
{children}
|
|
140
|
+
</RnghSwipeable>
|
|
141
|
+
</GestureHandlerRootView>
|
|
142
|
+
);
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export default Object.assign(Swipeable, {
|
|
146
|
+
Action: SwipeableAction,
|
|
147
|
+
Content: RectButton,
|
|
148
|
+
});
|
|
@@ -2,13 +2,7 @@ import { TextInput, View, StyleSheet } from 'react-native';
|
|
|
2
2
|
import styled from '@emotion/native';
|
|
3
3
|
import Typography from '../Typography';
|
|
4
4
|
|
|
5
|
-
export type Variant =
|
|
6
|
-
| 'default'
|
|
7
|
-
| 'filled'
|
|
8
|
-
| 'focused'
|
|
9
|
-
| 'disabled'
|
|
10
|
-
| 'readonly'
|
|
11
|
-
| 'error';
|
|
5
|
+
export type Variant = 'default' | 'filled' | 'disabled' | 'readonly' | 'error';
|
|
12
6
|
|
|
13
7
|
const StyledContainer = styled(View)(({ theme }) => ({
|
|
14
8
|
width: '100%',
|
|
@@ -99,12 +93,12 @@ const StyledTextInput = styled(TextInput)(({ theme }) => ({
|
|
|
99
93
|
|
|
100
94
|
const StyledBorderBackDrop = styled(View)<{
|
|
101
95
|
themeVariant: Variant;
|
|
102
|
-
|
|
96
|
+
themeFocused: boolean;
|
|
97
|
+
}>(({ theme, themeFocused, themeVariant }) => ({
|
|
103
98
|
...StyleSheet.absoluteFillObject,
|
|
104
|
-
borderWidth:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
: theme.__hd__.textInput.borderWidths.container.normal,
|
|
99
|
+
borderWidth: themeFocused
|
|
100
|
+
? theme.__hd__.textInput.borderWidths.container.focused
|
|
101
|
+
: theme.__hd__.textInput.borderWidths.container.normal,
|
|
108
102
|
borderRadius: theme.__hd__.textInput.radii.container,
|
|
109
103
|
borderColor:
|
|
110
104
|
theme.__hd__.textInput.colors.borders[themeVariant] ??
|
|
@@ -18,7 +18,6 @@ describe('Label', () => {
|
|
|
18
18
|
themeVariant
|
|
19
19
|
${'default'}
|
|
20
20
|
${'filled'}
|
|
21
|
-
${'focused'}
|
|
22
21
|
${'error'}
|
|
23
22
|
${'disabled'}
|
|
24
23
|
${'readonly'}
|
|
@@ -35,7 +34,6 @@ describe('LabelInsideTextInput', () => {
|
|
|
35
34
|
themeVariant
|
|
36
35
|
${'default'}
|
|
37
36
|
${'filled'}
|
|
38
|
-
${'focused'}
|
|
39
37
|
${'error'}
|
|
40
38
|
${'disabled'}
|
|
41
39
|
${'readonly'}
|
|
@@ -66,7 +64,6 @@ describe('StyledAsteriskLabel', () => {
|
|
|
66
64
|
themeVariant
|
|
67
65
|
${'default'}
|
|
68
66
|
${'filled'}
|
|
69
|
-
${'focused'}
|
|
70
67
|
${'error'}
|
|
71
68
|
${'disabled'}
|
|
72
69
|
${'readonly'}
|
|
@@ -105,7 +102,6 @@ describe('StyledMaxLengthMessage', () => {
|
|
|
105
102
|
themeVariant
|
|
106
103
|
${'default'}
|
|
107
104
|
${'filled'}
|
|
108
|
-
${'focused'}
|
|
109
105
|
${'error'}
|
|
110
106
|
${'disabled'}
|
|
111
107
|
${'readonly'}
|
|
@@ -138,7 +134,6 @@ describe('StyledBorderBackDrop', () => {
|
|
|
138
134
|
themeVariant
|
|
139
135
|
${'default'}
|
|
140
136
|
${'filled'}
|
|
141
|
-
${'focused'}
|
|
142
137
|
${'error'}
|
|
143
138
|
${'disabled'}
|
|
144
139
|
${'readonly'}
|
|
@@ -146,12 +141,23 @@ describe('StyledBorderBackDrop', () => {
|
|
|
146
141
|
'renders correctly with themeVariant $themeVariant',
|
|
147
142
|
({ themeVariant }): void => {
|
|
148
143
|
const { toJSON } = renderWithTheme(
|
|
149
|
-
<StyledBorderBackDrop
|
|
144
|
+
<StyledBorderBackDrop
|
|
145
|
+
themeVariant={themeVariant}
|
|
146
|
+
themeFocused={false}
|
|
147
|
+
/>
|
|
150
148
|
);
|
|
151
149
|
|
|
152
150
|
expect(toJSON()).toMatchSnapshot();
|
|
153
151
|
}
|
|
154
152
|
);
|
|
153
|
+
|
|
154
|
+
it('renders correctly when focused', (): void => {
|
|
155
|
+
const { toJSON } = renderWithTheme(
|
|
156
|
+
<StyledBorderBackDrop themeVariant="error" themeFocused />
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
expect(toJSON()).toMatchSnapshot();
|
|
160
|
+
});
|
|
155
161
|
});
|
|
156
162
|
|
|
157
163
|
describe('StyledTextInput', () => {
|