@fto-consult/expo-ui 8.58.1 → 8.58.3
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/package.json +1 -1
- package/src/components/Fab/Fab.js +1 -1
- package/src/components/Fab/FabItem/index.js +16 -0
- package/src/components/Fab/FabItem/old/FabItem.js +304 -0
- package/src/components/Fab/FabItem/utils.js +54 -0
- package/src/components/Fab/Group.js +1 -2
- package/src/components/Fab/GroupComponent.js +6 -10
- package/src/components/Fab/index.js +1 -1
- package/src/layouts/ProfilAvatar/index.js +1 -1
- package/src/screens/Help/openLibraries.js +7 -3
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@fto-consult/expo-ui",
|
3
|
-
"version": "8.58.
|
3
|
+
"version": "8.58.3",
|
4
4
|
"description": "Bibliothèque de composants UI Expo,react-native",
|
5
5
|
"react-native-paper-doc": "https://github.com/callstack/react-native-paper/tree/main/docs/docs/guides",
|
6
6
|
"scripts": {
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {FAB} from "react-native-paper";
|
3
|
+
import {defaultStr} from "$cutils";
|
4
|
+
import {standardSize as mediumSize,largeSize,smallSize} from "./utils";
|
5
|
+
const FabItemComponent = React.forwardRef(({size,style,...props},ref)=>{
|
6
|
+
size = defaultStr(size,"medium").toLowerCase().trim();
|
7
|
+
return <FAB
|
8
|
+
{...props}
|
9
|
+
size={size}
|
10
|
+
style = {[size == "small"? smallSize : size == "large"? largeSize : mediumSize,style]}
|
11
|
+
ref = {ref}
|
12
|
+
/>
|
13
|
+
});
|
14
|
+
FabItemComponent.displayName = "FabItemComponent";
|
15
|
+
|
16
|
+
export default FabItemComponent;
|
@@ -0,0 +1,304 @@
|
|
1
|
+
import * as React from 'react';
|
2
|
+
import {
|
3
|
+
Animated,
|
4
|
+
StyleSheet,
|
5
|
+
View,
|
6
|
+
} from 'react-native';
|
7
|
+
import PropTypes from "prop-types";
|
8
|
+
|
9
|
+
import {ActivityIndicator,Text,TouchableRipple,Surface} from "react-native-paper";
|
10
|
+
import { getExtendedFabStyle, getFABColors, getFabStyle } from '../utils';
|
11
|
+
import Icon from "$ecomponents/Icon";
|
12
|
+
import theme,{StyleProp} from "$theme";
|
13
|
+
|
14
|
+
const FAB = React.forwardRef(
|
15
|
+
(
|
16
|
+
{
|
17
|
+
icon,
|
18
|
+
label,
|
19
|
+
background,
|
20
|
+
accessibilityLabel = label,
|
21
|
+
accessibilityState,
|
22
|
+
animated = true,
|
23
|
+
color: customColor,
|
24
|
+
rippleColor: customRippleColor,
|
25
|
+
disabled,
|
26
|
+
onPress,
|
27
|
+
onLongPress,
|
28
|
+
delayLongPress,
|
29
|
+
theme: themeOverrides,
|
30
|
+
style,
|
31
|
+
visible = true,
|
32
|
+
uppercase: uppercaseProp,
|
33
|
+
loading,
|
34
|
+
testID = 'fab',
|
35
|
+
size = 'medium',
|
36
|
+
customSize,
|
37
|
+
mode = 'elevated',
|
38
|
+
variant = 'primary',
|
39
|
+
labelMaxFontSizeMultiplier,
|
40
|
+
...rest
|
41
|
+
},ref
|
42
|
+
) => {
|
43
|
+
const uppercase = uppercaseProp ?? !theme.isV3;
|
44
|
+
const { current: visibility } = React.useRef<Animated.Value>(
|
45
|
+
new Animated.Value(visible ? 1 : 0)
|
46
|
+
);
|
47
|
+
const { isV3, animation } = theme;
|
48
|
+
const { scale } = animation;
|
49
|
+
|
50
|
+
React.useEffect(() => {
|
51
|
+
if (visible) {
|
52
|
+
Animated.timing(visibility, {
|
53
|
+
toValue: 1,
|
54
|
+
duration: 200 * scale,
|
55
|
+
useNativeDriver: true,
|
56
|
+
}).start();
|
57
|
+
} else {
|
58
|
+
Animated.timing(visibility, {
|
59
|
+
toValue: 0,
|
60
|
+
duration: 150 * scale,
|
61
|
+
useNativeDriver: true,
|
62
|
+
}).start();
|
63
|
+
}
|
64
|
+
}, [visible, scale, visibility]);
|
65
|
+
|
66
|
+
const fabStyle = getFabStyle({ customSize, size, theme });
|
67
|
+
|
68
|
+
const {
|
69
|
+
borderRadius = fabStyle.borderRadius,
|
70
|
+
backgroundColor: customBackgroundColor,
|
71
|
+
} = (StyleSheet.flatten(style) || {});
|
72
|
+
|
73
|
+
const { backgroundColor, foregroundColor, rippleColor } = getFABColors({
|
74
|
+
theme,
|
75
|
+
variant,
|
76
|
+
disabled,
|
77
|
+
customColor,
|
78
|
+
customBackgroundColor,
|
79
|
+
customRippleColor,
|
80
|
+
});
|
81
|
+
|
82
|
+
const isLargeSize = size === 'large';
|
83
|
+
const isFlatMode = mode === 'flat';
|
84
|
+
const iconSize = isLargeSize ? 36 : 24;
|
85
|
+
const loadingIndicatorSize = isLargeSize ? 24 : 18;
|
86
|
+
const font = isV3 ? theme.fonts.labelLarge : theme.fonts.medium;
|
87
|
+
|
88
|
+
const extendedStyle = getExtendedFabStyle({ customSize, theme });
|
89
|
+
const textStyle = {
|
90
|
+
color: foregroundColor,
|
91
|
+
...font,
|
92
|
+
};
|
93
|
+
|
94
|
+
const md3Elevation = isFlatMode || disabled ? 0 : 3;
|
95
|
+
|
96
|
+
const newAccessibilityState = { ...accessibilityState, disabled };
|
97
|
+
|
98
|
+
return (
|
99
|
+
<Surface
|
100
|
+
ref={ref}
|
101
|
+
{...rest}
|
102
|
+
style={[
|
103
|
+
{
|
104
|
+
borderRadius,
|
105
|
+
backgroundColor,
|
106
|
+
opacity: visibility,
|
107
|
+
transform: [
|
108
|
+
{
|
109
|
+
scale: visibility,
|
110
|
+
},
|
111
|
+
],
|
112
|
+
},
|
113
|
+
!isV3 && styles.elevated,
|
114
|
+
!isV3 && disabled && styles.disabled,
|
115
|
+
style,
|
116
|
+
]}
|
117
|
+
pointerEvents={visible ? 'auto' : 'none'}
|
118
|
+
testID={`${testID}-container`}
|
119
|
+
{...(isV3 && { elevation: md3Elevation })}
|
120
|
+
>
|
121
|
+
<TouchableRipple
|
122
|
+
borderless
|
123
|
+
background={background}
|
124
|
+
onPress={onPress}
|
125
|
+
onLongPress={onLongPress}
|
126
|
+
delayLongPress={delayLongPress}
|
127
|
+
rippleColor={rippleColor}
|
128
|
+
disabled={disabled}
|
129
|
+
accessibilityLabel={accessibilityLabel}
|
130
|
+
accessibilityRole="button"
|
131
|
+
accessibilityState={newAccessibilityState}
|
132
|
+
testID={testID}
|
133
|
+
style={{ borderRadius }}
|
134
|
+
{...rest}
|
135
|
+
>
|
136
|
+
<View
|
137
|
+
style={[styles.content, label ? extendedStyle : fabStyle]}
|
138
|
+
testID={`${testID}-content`}
|
139
|
+
pointerEvents="none"
|
140
|
+
>
|
141
|
+
{icon && loading !== true ? (
|
142
|
+
<Icon
|
143
|
+
icon={icon}
|
144
|
+
size={customSize ? customSize / 2 : iconSize}
|
145
|
+
color={foregroundColor}
|
146
|
+
/>
|
147
|
+
) : null}
|
148
|
+
{loading ? (
|
149
|
+
<ActivityIndicator
|
150
|
+
size={customSize ? customSize / 2 : loadingIndicatorSize}
|
151
|
+
color={foregroundColor}
|
152
|
+
/>
|
153
|
+
) : null}
|
154
|
+
{label ? (
|
155
|
+
<Text
|
156
|
+
variant="labelLarge"
|
157
|
+
selectable={false}
|
158
|
+
testID={`${testID}-text`}
|
159
|
+
style={[
|
160
|
+
styles.label,
|
161
|
+
uppercase && styles.uppercaseLabel,
|
162
|
+
textStyle,
|
163
|
+
]}
|
164
|
+
maxFontSizeMultiplier={labelMaxFontSizeMultiplier}
|
165
|
+
>
|
166
|
+
{label}
|
167
|
+
</Text>
|
168
|
+
) : null}
|
169
|
+
</View>
|
170
|
+
</TouchableRipple>
|
171
|
+
</Surface>
|
172
|
+
);
|
173
|
+
}
|
174
|
+
);
|
175
|
+
|
176
|
+
const styles = StyleSheet.create({
|
177
|
+
elevated: {
|
178
|
+
elevation: 6,
|
179
|
+
},
|
180
|
+
content: {
|
181
|
+
flexDirection: 'row',
|
182
|
+
alignItems: 'center',
|
183
|
+
justifyContent: 'center',
|
184
|
+
},
|
185
|
+
label: {
|
186
|
+
marginHorizontal: 8,
|
187
|
+
},
|
188
|
+
uppercaseLabel: {
|
189
|
+
textTransform: 'uppercase',
|
190
|
+
},
|
191
|
+
disabled: {
|
192
|
+
elevation: 0,
|
193
|
+
},
|
194
|
+
});
|
195
|
+
|
196
|
+
FAB.propTypes = {
|
197
|
+
// For `icon` and `label` props their types are duplicated due to the generation of documentation.
|
198
|
+
// Appropriate type for them is `IconOrLabel` contains the both union and intersection types.
|
199
|
+
/**
|
200
|
+
* Icon to display for the `FAB`. It's optional only if `label` is defined.
|
201
|
+
*/
|
202
|
+
icon : PropTypes.shape({...Object.assign({},Icon.propTypes)}),
|
203
|
+
/**
|
204
|
+
* Optional label for extended `FAB`. It's optional only if `icon` is defined.
|
205
|
+
*/
|
206
|
+
label : PropTypes.node,
|
207
|
+
/**
|
208
|
+
* Make the label text uppercased.
|
209
|
+
*/
|
210
|
+
uppercase : PropTypes.bool,
|
211
|
+
/**
|
212
|
+
* Type of background drawabale to display the feedback (Android).
|
213
|
+
* https://reactnative.dev/docs/pressable#rippleconfig
|
214
|
+
*/
|
215
|
+
background : PropTypes.any,
|
216
|
+
/**
|
217
|
+
* Accessibility label for the FAB. This is read by the screen reader when the user taps the FAB.
|
218
|
+
* Uses `label` by default if specified.
|
219
|
+
*/
|
220
|
+
accessibilityLabel : PropTypes.string,
|
221
|
+
/**
|
222
|
+
* Whether an icon change is animated.
|
223
|
+
*/
|
224
|
+
animated : PropTypes.bool,
|
225
|
+
/**
|
226
|
+
* @deprecated Deprecated in v.5x - use prop size="small".
|
227
|
+
*
|
228
|
+
* Whether FAB is mini-sized, used to create visual continuity with other elements. This has no effect if `label` is specified.
|
229
|
+
*/
|
230
|
+
small : PropTypes.bool,
|
231
|
+
/**
|
232
|
+
* Custom color for the icon and label of the `FAB`.
|
233
|
+
*/
|
234
|
+
color : PropTypes.string,
|
235
|
+
/**
|
236
|
+
* Color of the ripple effect.
|
237
|
+
*/
|
238
|
+
rippleColor : PropTypes.string,
|
239
|
+
/**
|
240
|
+
* Whether `FAB` is disabled. A disabled button is greyed out and `onPress` is not called on touch.
|
241
|
+
*/
|
242
|
+
disabled: PropTypes.bool,
|
243
|
+
/**
|
244
|
+
* Whether `FAB` is currently visible.
|
245
|
+
*/
|
246
|
+
visible: PropTypes.bool,
|
247
|
+
/**
|
248
|
+
* Whether to show a loading indicator.
|
249
|
+
*/
|
250
|
+
loading: PropTypes.bool,
|
251
|
+
/**
|
252
|
+
* Function to execute on press.
|
253
|
+
*/
|
254
|
+
onPress: PropTypes.func,
|
255
|
+
/**
|
256
|
+
* Function to execute on long press.
|
257
|
+
*/
|
258
|
+
onLongPress: PropTypes.func,
|
259
|
+
/**
|
260
|
+
* The number of milliseconds a user must touch the element before executing `onLongPress`.
|
261
|
+
*/
|
262
|
+
delayLongPress : PropTypes.number,
|
263
|
+
/**
|
264
|
+
* @supported Available in v5.x with theme version 3
|
265
|
+
*
|
266
|
+
* Size of the `FAB`.
|
267
|
+
* - `small` - FAB with small height (40).
|
268
|
+
* - `medium` - FAB with default medium height (56).
|
269
|
+
* - `large` - FAB with large height (96).
|
270
|
+
*/
|
271
|
+
size : PropTypes.oneOf([`small`,`medium`,`large`]),
|
272
|
+
/**
|
273
|
+
* Custom size for the `FAB`. This prop takes precedence over size prop
|
274
|
+
*/
|
275
|
+
customSize : PropTypes.number,
|
276
|
+
/**
|
277
|
+
* @supported Available in v5.x with theme version 3
|
278
|
+
*
|
279
|
+
* Mode of the `FAB`. You can change the mode to adjust the the shadow:
|
280
|
+
* - `flat` - button without a shadow.
|
281
|
+
* - `elevated` - button with a shadow.
|
282
|
+
*/
|
283
|
+
mode : PropTypes.oneOf([`flat`,`elevated`]),
|
284
|
+
/**
|
285
|
+
* @supported Available in v5.x with theme version 3
|
286
|
+
*
|
287
|
+
* Color mappings variant for combinations of container and icon colors.
|
288
|
+
*/
|
289
|
+
variant : PropTypes.oneOf(['primary' , 'secondary' , 'tertiary' , 'surface']),
|
290
|
+
/**
|
291
|
+
* Specifies the largest possible scale a label font can reach.
|
292
|
+
*/
|
293
|
+
labelMaxFontSizeMultiplier : PropTypes.number,
|
294
|
+
style : StyleProp,
|
295
|
+
/**
|
296
|
+
* TestID used for testing purposes
|
297
|
+
*/
|
298
|
+
testID: PropTypes.string,
|
299
|
+
}
|
300
|
+
|
301
|
+
export default FAB;
|
302
|
+
|
303
|
+
// @component-docs ignore-next-line
|
304
|
+
export { FAB };
|
@@ -0,0 +1,54 @@
|
|
1
|
+
const getCustomFabSize = (customSize, roundness) => ({
|
2
|
+
height: customSize,
|
3
|
+
width: customSize,
|
4
|
+
borderRadius: roundness === 0 ? 0 : customSize / roundness,
|
5
|
+
});
|
6
|
+
|
7
|
+
export const standardSize = {
|
8
|
+
height: 56,
|
9
|
+
width: 56,
|
10
|
+
borderRadius: 28,
|
11
|
+
};
|
12
|
+
export const smallSize = {
|
13
|
+
height: 40,
|
14
|
+
width: 40,
|
15
|
+
borderRadius: 28,
|
16
|
+
};
|
17
|
+
export const largeSize = {
|
18
|
+
height: 96,
|
19
|
+
width: 96,
|
20
|
+
borderRadius : 45,
|
21
|
+
}
|
22
|
+
const v3SmallSize = {
|
23
|
+
height: 40,
|
24
|
+
width: 40,
|
25
|
+
};
|
26
|
+
const v3MediumSize = {
|
27
|
+
height: 56,
|
28
|
+
width: 56,
|
29
|
+
};
|
30
|
+
const v3LargeSize = {
|
31
|
+
height: 96,
|
32
|
+
width: 96,
|
33
|
+
};
|
34
|
+
|
35
|
+
export const getFabStyle = ({size,theme,customSize}) => {
|
36
|
+
const { isV3, roundness } = theme;
|
37
|
+
|
38
|
+
if (customSize) return getCustomFabSize(customSize, roundness);
|
39
|
+
|
40
|
+
if (isV3) {
|
41
|
+
switch (size) {
|
42
|
+
case 'small':
|
43
|
+
return { ...v3SmallSize, borderRadius: 3 * roundness };
|
44
|
+
case 'medium':
|
45
|
+
return { ...v3MediumSize, borderRadius: 4 * roundness };
|
46
|
+
case 'large':
|
47
|
+
return { ...v3LargeSize, borderRadius: 7 * roundness };
|
48
|
+
}
|
49
|
+
}
|
50
|
+
if (size === 'small') {
|
51
|
+
return smallSize;
|
52
|
+
}
|
53
|
+
return standardSize;
|
54
|
+
};
|
@@ -1,4 +1,4 @@
|
|
1
|
-
import
|
1
|
+
import FAB from "./FabItem";
|
2
2
|
import React from "$react";
|
3
3
|
import {StyleSheet} from "react-native";
|
4
4
|
import {defaultStr,isNonNullString,isObj,defaultObj} from "$cutils";
|
@@ -184,7 +184,6 @@ const actionType = PropTypes.shape({
|
|
184
184
|
small : PropTypes.bool,
|
185
185
|
});
|
186
186
|
FabGroupComponent.propTypes = {
|
187
|
-
...defaultObj(FAB.Group.propTypes),
|
188
187
|
fabId : PropTypes.string,//l'id du fab
|
189
188
|
onMount : PropTypes.func, ///lorsque le composant est monté
|
190
189
|
onUnmount : PropTypes.func, //lorsque le composant est démonté
|
@@ -6,14 +6,12 @@ import {
|
|
6
6
|
TouchableWithoutFeedback
|
7
7
|
} from 'react-native';
|
8
8
|
import View from "$ecomponents/View";
|
9
|
-
import {
|
10
|
-
import colorFn from 'color';
|
9
|
+
import {Text,Card,withTheme} from "react-native-paper";
|
11
10
|
import PropTypes from "prop-types";
|
12
11
|
import Action from "$ecomponents/Form/Action";
|
13
12
|
import theme,{ disabledStyle,StylePropTypes,cursorPointer,Colors,cursorNotAllowed } from '$theme';
|
14
13
|
import {defaultStr} from "$cutils";
|
15
|
-
|
16
|
-
|
14
|
+
import CustomFabItem from "./FabItem";
|
17
15
|
|
18
16
|
const FABGroup = ({
|
19
17
|
actions,
|
@@ -159,8 +157,8 @@ const FABGroup = ({
|
|
159
157
|
)
|
160
158
|
})}
|
161
159
|
</View>
|
162
|
-
<
|
163
|
-
|
160
|
+
<CustomFabItem
|
161
|
+
size = 'medium'
|
164
162
|
{...defaultObj(rest)}
|
165
163
|
onPress={() => {
|
166
164
|
onPress?.();
|
@@ -204,7 +202,6 @@ FABGroup.propTypes = {
|
|
204
202
|
* - `labelTextColor`: custom label text color of the action item
|
205
203
|
* - `style`: pass additional styles for the fab item, for example, `backgroundColor`
|
206
204
|
* - `labelStyle`: pass additional styles for the fab item label, for example, `backgroundColor`
|
207
|
-
* - `small`: boolean describing whether small or normal sized FAB is rendered. Defaults to `true`
|
208
205
|
* - `onPress`: callback that is called when `FAB` is pressed (required)
|
209
206
|
*/
|
210
207
|
actions: PropTypes.arrayOf(PropTypes.shape({
|
@@ -214,7 +211,6 @@ FABGroup.propTypes = {
|
|
214
211
|
labelTextColor: PropTypes.string,
|
215
212
|
style: StylePropTypes,
|
216
213
|
labelStyle: StylePropTypes,
|
217
|
-
small: PropTypes.bool,
|
218
214
|
onPress: PropTypes.func,
|
219
215
|
testID: PropTypes.string,
|
220
216
|
})),
|
@@ -314,8 +310,8 @@ const _FabItem = function({children,label,disabled:customDisabled,pointerEvents,
|
|
314
310
|
</Card>
|
315
311
|
</View>
|
316
312
|
) : null}
|
317
|
-
<
|
318
|
-
|
313
|
+
<CustomFabItem
|
314
|
+
size={typeof small =='boolean' && small ? "small":"medium"}
|
319
315
|
icon={icon}
|
320
316
|
color={color}
|
321
317
|
disabled = {disabled}
|
@@ -1,8 +1,12 @@
|
|
1
1
|
module.exports = {
|
2
2
|
"@fto-consult/expo-ui": {
|
3
|
-
"
|
4
|
-
"
|
5
|
-
"
|
3
|
+
"name": "@fto-consult/expo-ui",
|
4
|
+
"version": "8.58.2",
|
5
|
+
"repository": {
|
6
|
+
"type": "git",
|
7
|
+
"url": "git+https://github.com/borispipo/expo-ui.git"
|
8
|
+
},
|
9
|
+
"homepage": "https://github.com/borispipo/expo-ui#readme"
|
6
10
|
},
|
7
11
|
"@babel/plugin-proposal-export-namespace-from": {
|
8
12
|
"version": "7.18.9",
|