-
Notifications
You must be signed in to change notification settings - Fork 6
/
index.tsx
160 lines (146 loc) · 5.57 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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
import React from 'react';
import { ViewProps, StyleProp, StyleSheet, ViewStyle, View, GestureResponderEvent, Pressable, PressableStateCallbackType } from 'react-native';
import { getColor } from '../../styles/colors';
import { createIcon, pressableFeedbackStyle, styleReferenceBreaker } from '../../helpers';
import type { ToolbarButton } from '../../types/navigation';
import { Button } from '../Button';
import { Link } from '../Link';
import type { CarbonIcon } from '../../types/shared';
export type BottomToolbarPrimaryActionProps = {
/** Position of primary action (default is center) */
position?: 'center' | 'right' | 'left';
/** Icon to load for the primary action (size 24) */
icon: CarbonIcon;
/** Text to use to describe the primary action (for accessibility) */
text: string;
/** Indicate if primary action is disabled */
disabled?: boolean;
/** onPress event for primary button item */
onPress?: (event: GestureResponderEvent) => void;
/** onLongPress event for primary button item */
onLongPress?: (event: GestureResponderEvent) => void;
/** Toolbar items to load for left side. Not used for positon left. (alignment property is not respected in this view) */
leftItems?: ToolbarButton[];
/** Toolbar items to load for right side. Not used for positon right. (alignment property is not respected in this view) */
rightItems?: ToolbarButton[];
/** Style to set on the item */
style?: StyleProp<ViewStyle>;
/** Direct props to set on the React Native component (including iOS and Android specific props). Most use cases should not need this. */
componentProps?: ViewProps;
};
export class BottomToolbarPrimaryAction extends React.Component<BottomToolbarPrimaryActionProps> {
private get styles() {
return StyleSheet.create({
wrapper: {
height: 48,
maxHeight: 48,
width: '100%',
backgroundColor: getColor('layer01'),
flexDirection: 'row',
position: 'relative',
borderTopColor: getColor('borderSubtle01'),
borderTopWidth: 1,
},
itemWrapper: {
flex: 1,
flexDirection: 'row',
},
primaryAction: {
marginRight: 16,
marginLeft: 16,
width: 56,
height: 56,
backgroundColor: getColor('buttonPrimary'),
padding: 16,
borderRadius: 56,
marginTop: -28,
},
itemTextStyle: {
flex: 1,
},
itemIconStyle: {
width: 48,
},
linkStyle: {
padding: 13,
},
});
}
private getItems(items: ToolbarButton[], type: 'right' | 'left'): React.ReactNode {
const finalWrapperStyles = styleReferenceBreaker(this.styles.itemWrapper);
if (type === 'right') {
finalWrapperStyles.justifyContent = 'flex-end';
} else if (type === 'left') {
finalWrapperStyles.justifyContent = 'flex-start';
}
return (
<View style={finalWrapperStyles}>
{items.map((item, index) => {
const iconMode = !!item.icon;
const finalStyles = styleReferenceBreaker(iconMode ? this.styles.itemIconStyle : this.styles.itemTextStyle, item.style);
let finalColor = getColor('iconPrimary');
if (item.disabled) {
finalColor = getColor('iconDisabled');
}
return (
<View style={finalStyles} key={index}>
{iconMode ? <Button kind="ghost" overrideColor={finalColor} disabled={item.disabled} icon={item.icon} iconOnlyMode={true} text={item.text} onPress={item.onPress} onLongPress={item.onLongPress} /> : <Link style={this.styles.linkStyle} disabled={item.disabled} textStyle={{ textAlign: item.alignItem || 'center' }} textType={item.textType} text={item.text} onPress={item.onPress} onLongPress={item.onLongPress} />}
</View>
);
})}
</View>
);
}
private get primaryAction(): React.ReactNode {
const { disabled, icon, text, onPress, onLongPress } = this.props;
const finalStyles = styleReferenceBreaker(this.styles.primaryAction);
const getStateStyle = (state: PressableStateCallbackType): StyleProp<ViewStyle> => {
return state.pressed ? { backgroundColor: getColor('buttonPrimaryActive') } : undefined;
};
if (disabled) {
finalStyles.backgroundColor = getColor('buttonDisabled');
}
return (
<Pressable disabled={disabled} style={(state) => pressableFeedbackStyle(state, finalStyles, getStateStyle)} onPress={onPress} onLongPress={onLongPress} accessibilityLabel={text} accessibilityRole="button">
{createIcon(icon, 24, 24, getColor(disabled ? 'textOnColorDisabled' : 'textOnColor'))}
</Pressable>
);
}
private get mainView(): React.ReactNode {
const { position, leftItems, rightItems } = this.props;
switch (position) {
case 'left':
return (
<>
{this.primaryAction}
{this.getItems(rightItems || [], 'right')}
</>
);
case 'right':
return (
<>
{this.getItems(leftItems || [], 'left')}
{this.primaryAction}
</>
);
case 'center':
default:
return (
<>
{this.getItems(leftItems || [], 'left')}
{this.primaryAction}
{this.getItems(rightItems || [], 'right')}
</>
);
}
}
render(): React.ReactNode {
const { componentProps, style } = this.props;
const finalStyles = styleReferenceBreaker(this.styles.wrapper, style);
return (
<View style={finalStyles} accessibilityRole="toolbar" {...(componentProps || {})}>
{this.mainView}
</View>
);
}
}