@fto-consult/expo-ui 5.4.0 → 5.5.2

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/bin/init.js CHANGED
@@ -31,8 +31,8 @@ module.exports = ({
31
31
  "package" : "npx expo-ui electron package",
32
32
  "compile2package" : "npx expo-ui electron package compile"
33
33
  }
34
+ projectRootPackage.name = projectRootPackage.name.trim().toUpperCase();
34
35
  projectRootPackage.realAppName = typeof projectRootPackage.realAppName =="string" && projectRootPackage.realAppName || projectRootPackage.name;
35
- projectRootPackage.name = projectRootPackage.name.trim();
36
36
  if(!projectRootPackage.name.endsWith(appSuffix)){
37
37
  projectRootPackage.name +=appSuffix;
38
38
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fto-consult/expo-ui",
3
- "version": "5.4.0",
3
+ "version": "5.5.2",
4
4
  "description": "Bibliothèque de composants UI Expo,react-native",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -61,7 +61,7 @@
61
61
  "@emotion/native": "^11.10.0",
62
62
  "@expo/html-elements": "^0.2.0",
63
63
  "@expo/vector-icons": "^13.0.0",
64
- "@fto-consult/common": "^3.3.5",
64
+ "@fto-consult/common": "^3.4.1",
65
65
  "@gorhom/portal": "^1.0.14",
66
66
  "@react-native-async-storage/async-storage": "^1.17.11",
67
67
  "@react-native-community/datetimepicker": "^6.7.3",
@@ -95,9 +95,10 @@
95
95
  "react-native-big-list": "^1.6.0",
96
96
  "react-native-blob-util": "^0.17.0",
97
97
  "react-native-gesture-handler": "~2.9.0",
98
+ "react-native-iphone-x-helper": "^1.3.1",
98
99
  "react-native-mime-types": "^2.3.0",
99
- "react-native-paper": "^4.12.5",
100
- "react-native-paper-dates": "^0.9.2",
100
+ "react-native-paper": "^5.4.1",
101
+ "react-native-paper-dates": "^0.15.1",
101
102
  "react-native-reanimated": "~2.14.4",
102
103
  "react-native-safe-area-context": "^4.5.0",
103
104
  "react-native-screens": "~3.20.0",
@@ -26,6 +26,7 @@ const renderAction = ({action,isAlert,actionProps,opts,isAppBarAction,isAppBarAc
26
26
  rest = Object.assign({},rest);
27
27
  rest.accessibilityLabel = defaultStr(rest.accessibilityLabel,rest.title,rest.text,rest.label,rest.children);
28
28
  const color = theme.colors.primaryText;
29
+
29
30
  rest.style = {...defaultObj(StyleSheet.flatten(actionProps.style)),elevation:0,...defaultObj(StyleSheet.flatten(rest.style))};
30
31
  if(isAppBarActionStyle !== false && (isAppBarAction || opts.isAppBarAction)){
31
32
  rest.color = defaultVal(color);
@@ -6,35 +6,32 @@ import {defaultObj,defaultDecimal,defaultStr,isDecimal,defaultBool} from "$utils
6
6
  import View from "$ecomponents/View";
7
7
  import PropTypes from "prop-types";
8
8
  import {getContentHeight} from "./utils";
9
+ import Dimensions from "$dimensions";
9
10
 
10
11
  const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
11
12
  let {anchor,anchorProps,screenIndent,height:customHeight,bindResizeEvent,onDismiss,testID,visible:customVisible,controlled,mobile,animateOnClose,renderMenuContent,sheet,children,...rest} = props;
12
13
  rest = defaultObj(rest);
13
14
  const isControlled = controlled ? true : false;
14
- const visibleRef = React.useRef(null);
15
15
  const [state,setState] = React.useState({
16
16
  visible : false,
17
17
  height : undefined,
18
18
  });
19
- const visible = typeof visibleRef.current =='boolean'? visibleRef.current : isControlled ? customVisible : state.visible;
20
- visibleRef.current = null;
19
+ const [key,setKey] = React.useState(false);
20
+ const visible = isControlled ? customVisible : state.visible;
21
21
  let height = state.height;
22
22
  const isMounted = React.useIsMounted();
23
23
  const anchorRef = React.useRef(null);
24
- const isMobile = x=> mobile || sheet === true || renderMenuContent === false || isMobileMedia() ? true : false;
25
- let isMob = isMobile();
24
+ const isMob = mobile || sheet === true || renderMenuContent === false || Dimensions.isMobileOrTabletMedia() ? true : false;
26
25
  testID = defaultStr(testID,'RN_BottomSheetMenuComponent');
27
26
  const innerRef = React.useRef(null);
28
27
  const open = (event)=>{
29
- if(!isMobile()) return;
30
28
  React.stopEventPropagation(event);
31
- if(!isMounted() || visible) return;
29
+ if(!isMounted()) return;
32
30
  getContentHeight(anchorRef,({height})=>{
33
31
  setState({...state,visible:true,height});
34
32
  },screenIndent);
35
33
  }, close = ()=>{
36
- if(!isMobile()) return;
37
- if(!isMounted() || !visible) return;
34
+ if(!isMounted()) return;
38
35
  if(isControlled){
39
36
  if(onDismiss){
40
37
  onDismiss({});
@@ -43,6 +40,7 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
43
40
  }
44
41
  setState({...state,visible:false})
45
42
  }
43
+ const prevIsMob = React.usePrevious(isMob);
46
44
  const Component = isMob ? BottomSheet : Menu;
47
45
  anchorProps = defaultObj(anchorProps);
48
46
  if(isMob){
@@ -67,6 +65,9 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
67
65
  delete rest.visible;
68
66
  height = undefined;
69
67
  }
68
+ if(prevIsMob !== isMob){
69
+ rest.visible = visible;
70
+ }
70
71
  if(!isControlled){
71
72
  rest.onAnchorPress = ()=>{
72
73
  open();
@@ -77,8 +78,7 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
77
78
  React.useEffect(()=>{
78
79
  const closeModal = ()=>{
79
80
  if(!isMounted()) return;
80
- visibleRef.current = false;
81
- setState({...state});
81
+ setKey(!key);
82
82
  }
83
83
  if(bindResizeEvent !== false){
84
84
  APP.on(APP.EVENTS.RESIZE_PAGE,closeModal);
@@ -97,7 +97,7 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
97
97
  {isMob && React.isValidElement(anchor)? anchor : null}
98
98
  <Component
99
99
  {...rest}
100
- bindResizeEvent = {false}
100
+ key = {isMob?"mobile":"desktop"}
101
101
  testID = {testID}
102
102
  height = {controlled?customHeight:height}
103
103
  ref = {React.useMergeRefs(innerRef,ref)}
@@ -106,7 +106,6 @@ const BottomSheetMenuComponent = React.forwardRef((props,ref)=>{
106
106
  children = {visible && (React.isValidElement(children) || Array.isArray(children))?children:undefined}
107
107
  />
108
108
  </>
109
-
110
109
  })
111
110
 
112
111
  BottomSheetMenuComponent.propTypes = {
@@ -14,53 +14,54 @@ import Label from "$ecomponents/Label";
14
14
  import {defaultObj,defaultVal,defaultDecimal,defaultStr} from "$utils";
15
15
 
16
16
  import PropTypes from "prop-types";
17
- const white = "white",black = "black";
17
+ const white = "white";
18
18
 
19
- const ButtonComponent = React.forwardRef(({
20
- disabled:customDisabled,
21
- compact,
22
- mode = 'text',
23
- dark,
24
- loading,
25
- icon,
26
- color: buttonColor,
27
- children,
28
- text,
29
- label,
30
- isCancelButton,
31
- error,
32
- upperCase = true,
33
- accessibilityLabel,
34
- onPress,
35
- iconPosition,
36
- iconBefore,
37
- onLongPress,
38
- style,
39
- contentStyle,
40
- contentProps,
41
- labelStyle,
42
- labelProps,
43
- testID,
44
- iconSize,
45
- iconProps,
46
- left,
47
- elevation : customElevation,
48
- right,
49
- accessible,
50
- backgroundColor,
51
- borderColor,
52
- accessibilityRole,
53
- contentContainerProps,
54
- loadingProps,
55
- rounded,
56
- containerProps,
57
- disableRipple,
58
- noPadding,
59
- noMargin,
60
- isAlert,
61
- borderRadius,
62
- ...rest
63
- },ref) => {
19
+ const ButtonComponent = React.forwardRef((prs,ref) => {
20
+ let {
21
+ disabled:customDisabled,
22
+ compact,
23
+ mode = 'text',
24
+ dark,
25
+ loading,
26
+ icon,
27
+ color: buttonColor,
28
+ children,
29
+ text,
30
+ label,
31
+ isCancelButton,
32
+ error,
33
+ upperCase = true,
34
+ accessibilityLabel,
35
+ onPress,
36
+ iconPosition,
37
+ iconBefore,
38
+ onLongPress,
39
+ style:customStyle,
40
+ contentStyle,
41
+ contentProps,
42
+ labelStyle,
43
+ labelProps,
44
+ testID,
45
+ iconSize,
46
+ iconProps,
47
+ left,
48
+ elevation : customElevation,
49
+ right,
50
+ accessible,
51
+ backgroundColor,
52
+ borderColor,
53
+ accessibilityRole,
54
+ contentContainerProps,
55
+ loadingProps,
56
+ rounded,
57
+ containerProps,
58
+ disableRipple,
59
+ noPadding,
60
+ noMargin,
61
+ isAlert,
62
+ borderRadius,
63
+ ...rest
64
+ } = prs;
64
65
  isCancelButton = isCancelButton || error && true || false;
65
66
  children = defaultVal(children,label,text);
66
67
  testID = defaultStr(testID,'RN_ButtonComponent');
@@ -140,25 +141,22 @@ const ButtonComponent = React.forwardRef(({
140
141
  };
141
142
  contentContainerProps = defaultObj(contentContainerProps);
142
143
  containerProps = defaultObj(containerProps);
143
- style = Object.assign(StyleSheet.flatten(style) || {});
144
+ const style = StyleSheet.flatten(customStyle) || {};
145
+
144
146
  labelStyle = StyleSheet.flatten([labelStyle]);
145
147
  const disabled = isDisabled || isLoading;
146
- let textColor = Colors.isValid(buttonColor)?buttonColor : Colors.isValid(labelStyle.color) ? labelStyle.color : Colors.isValid(style.color)? style.color : isCancelButton? theme.colors.errorText : theme.colors.primary,
148
+ let textColor = Colors.isValid(style.color)? style.color : Colors.isValid(buttonColor)?buttonColor : isCancelButton? theme.colors.errorText : Colors.isValid(labelStyle.color) ? labelStyle.color : theme.colors.primary,
147
149
  borderWidth;
148
150
  const restButtonStyle = {
149
151
  opacity : disabled ? DISABLED_OPACITY : undefined
150
- };
151
-
152
+ };
153
+
152
154
  iconProps = defaultObj(iconProps);
153
155
  labelProps = defaultObj(labelProps);
154
156
  contentProps = defaultObj(contentProps);
155
- if(isCancelButton){
156
- style.backgroundColor = theme.colors.error;
157
- style.color = theme.styles.errorText ;
158
- }
159
157
  if (!disabled && hasElevation) {
160
- backgroundColor = Colors.isValid(backgroundColor)? backgroundColor : Colors.isValid(style.backgroundColor)?style.backgroundColor : undefined;
161
- borderColor = Colors.isValid(borderColor)? borderColor : Colors.isValid(style.borderColor)? style.borderColor : isCancelButton ? theme.styles.errorText : undefined;
158
+ backgroundColor = Colors.isValid(style.backgroundColor)?style.backgroundColor : Colors.isValid(backgroundColor)? backgroundColor : isCancelButton ? style.backgroundColor = theme.colors.error : undefined;
159
+ borderColor = Colors.isValid(style.borderColor)? style.borderColor : isCancelButton ? theme.styles.errorText : Colors.isValid(borderColor)? borderColor : undefined;
162
160
  }
163
161
  if(theme.isDark() && !hasElevation){
164
162
  textColor = white;
@@ -6,6 +6,7 @@ import {MORE_ICON} from "$ecomponents/Icon/utils";
6
6
  import {renderActions} from "./utils";
7
7
  import View from "$ecomponents/View";
8
8
  import { StyleSheet } from "react-native";
9
+ import DialogActions from "./RNPDialogActions";
9
10
 
10
11
  const DialogActionsComponent = React.forwardRef(({actions,isAlert,onAlertRequestClose,testID,containerProps,actionMutator,actionProps,cancelButton,responsive,isFullScreen,fullScreen,actionsProps,menuProps,...rest},ref)=>{
11
12
  const forceRender = React.useForceRender();
@@ -35,7 +36,7 @@ const DialogActionsComponent = React.forwardRef(({actions,isAlert,onAlertRequest
35
36
  testID = testID||'DialogComponent_Actions';
36
37
  if(menuActions && (menuActions.actions.length || menuActions.menus.length)){
37
38
  return <View testID={testID} {...containerProps} style={[styles.container,containerProps.style]} ref={ref}>
38
- <Dialog.Actions testID={testID+"_ActionsContainer"} {...rest} style={[styles.actions,rest.style]}>
39
+ <DialogActions testID={testID+"_ActionsContainer"} {...rest} style={[styles.actions,rest.style]}>
39
40
  {menuActions.actions}
40
41
  {menuActions.menus.length ? <Menu
41
42
  testID = {testID+"_MenuWrapper"}
@@ -47,7 +48,7 @@ const DialogActionsComponent = React.forwardRef(({actions,isAlert,onAlertRequest
47
48
  }}
48
49
  items = {menuActions.menus}
49
50
  />: null}
50
- </Dialog.Actions>
51
+ </DialogActions>
51
52
  </View>
52
53
  }
53
54
  return null;
@@ -0,0 +1,53 @@
1
+ import * as React from 'react';
2
+ import { StyleSheet, View,} from 'react-native';
3
+ import PropTypes from "prop-types";
4
+ import { StyleProp } from '$theme';
5
+ import {defaultStr} from "$utils";
6
+
7
+ const DialogActions = ({testID,...props}) => {
8
+ testID = defaultStr(testID,"RNP_DialogActionsComponent")
9
+ return (
10
+ <View
11
+ {...props}
12
+ testID = {testID}
13
+ style={[styles.container, props.style]}
14
+ >
15
+ {React.Children.map(props.children, (child, i) =>
16
+ React.isValidElement(child)
17
+ ? React.cloneElement(child, {
18
+ compact: true,
19
+ testID : defaultStr(child?.props?.testID,testID+"_Action"),
20
+ //style: child?.props?.style,
21
+ })
22
+ : child
23
+ )}
24
+ </View>
25
+ );
26
+ };
27
+
28
+ DialogActions.displayName = 'Dialog.Actions';
29
+
30
+ const styles = StyleSheet.create({
31
+ container: {
32
+ flexDirection: 'row',
33
+ alignItems: 'center',
34
+ justifyContent: 'flex-end',
35
+ padding: 8,
36
+ },
37
+ v3Container: {
38
+ flexDirection: 'row',
39
+ flexGrow: 1,
40
+ alignItems: 'center',
41
+ justifyContent: 'flex-end',
42
+ paddingBottom: 24,
43
+ paddingHorizontal: 24,
44
+ },
45
+ });
46
+
47
+ export default DialogActions;
48
+
49
+
50
+ DialogActions.propTypes = {
51
+ children: PropTypes.node,
52
+ style : StyleProp,
53
+ }
@@ -56,6 +56,7 @@ export default function showConfirm (p,cb){
56
56
  if(isNonNullString(yes)){
57
57
  yes = {text:yes}
58
58
  }
59
+ testID = defaultStr(testID,"RN_AlertDialogComponent");
59
60
  buttons = defaultVal(buttons,actions);
60
61
  if(buttons !== false && buttons !== null){
61
62
  if(!isArray(buttons)){
@@ -67,6 +68,7 @@ export default function showConfirm (p,cb){
67
68
  if(!alert && no !== false){
68
69
  no.text = defaultStr(no.text,'Non');
69
70
  const {onPress} = no;
71
+ no.testID = testID+"_NoCancelButton";
70
72
  no.style = [{color:theme.colors.errorText,backgroundColor:theme.colors.error},no.style];
71
73
  no.onPress = (args)=>{
72
74
  args = React.getOnPressArgs(args);
@@ -80,6 +82,7 @@ export default function showConfirm (p,cb){
80
82
  if(yes !== false){
81
83
  yes = defaultObj(yes,ok)
82
84
  yes.text = defaultStr(yes.text,alert?'OK':'Oui');
85
+ yes.testID = testID+"_YesOkButton";
83
86
  yes.style = [{color:theme.colors.primaryText,backgroundColor:theme.colors.primary},yes.style]
84
87
  const {onPress} = yes;
85
88
  yes.onPress = (args)=>{
@@ -98,7 +101,6 @@ export default function showConfirm (p,cb){
98
101
  if(confirm){
99
102
  alert = true;
100
103
  }
101
- testID = defaultStr(testID,"RN_AlertDialogComponent");
102
104
  const messageContent = React.isValidElement(message,true)?<Label testID={testID+"_Message"} {...messageProps} style={[theme.styles.fs15,theme.styles.pb1,messageProps.style]} >{message}</Label> :null;
103
105
  if(alert){
104
106
  return Alert.alert({
@@ -32,11 +32,11 @@ import Zocial from "@expo/vector-icons/Zocial";
32
32
  * simple-line - pour l'iconSet SimpleLinesIcons
33
33
  * zocial - pour l'iconSet Zocial
34
34
  */
35
- const FontIcon = React.forwardRef(({icon,name,testID,color,iconStyle,backgroundColor,style,...props},ref)=>{
35
+ const FontIcon = React.forwardRef(({icon,name,testID,color,iconColor,iconStyle,backgroundColor,style,...props},ref)=>{
36
36
  icon = defaultStr(icon,name).trim();
37
37
  testID = defaultStr(testID,"RN_FontIconComponent");
38
38
  const fStyle = StyleSheet.flatten(style) || {};
39
- color = theme.Colors.isValid(color)? color : fStyle.color || theme.colors.text;
39
+ color = theme.Colors.isValid(color)? color : Colors.isValid(iconColor)?iconColor : fStyle.color || theme.colors.text;
40
40
  backgroundColor = theme.Colors.isValid(backgroundColor)? backgroundColor : fStyle.backgroundColor || 'transparent';
41
41
  const isMaterial = isIcon(name,"material");
42
42
  const isFa = isIcon(name,"fa");
@@ -65,11 +65,11 @@ const FontIcon = React.forwardRef(({icon,name,testID,color,iconStyle,backgroundC
65
65
  .ltrim("fa-").ltrim("ant-").ltrim("fontisto-")
66
66
  .ltrim("foundation-").ltrim("ionic-").ltrim("octicons-")
67
67
  .ltrim("simple-line-").ltrim("zocial-").trim();
68
-
69
68
  return <Icon {...props}
70
69
  ref = {ref}
71
70
  testID = {testID}
72
71
  color={color}
72
+ iconColor = {iconColor}
73
73
  name = {iconName}
74
74
  backgroundColor = {backgroundColor}
75
75
  />
@@ -22,10 +22,12 @@ const IconComponentRef = React.forwardRef((props,ref)=>{
22
22
  if(button === false){
23
23
  flattenedStyle.borderRadius = 0;
24
24
  }
25
+ const iconColor = Colors.isValid(color) ? color : Colors.isValid(rest.iconColor)? rest.iconColor : Colors.isValid(flattenedStyle.color)? flattenedStyle.color : theme.colors.text
25
26
  return <Tooltip
26
27
  animated
27
28
  {...rest}
28
- color={Colors.isValid(color) ? color : Colors.isValid(flattenedStyle.color)? flattenedStyle.color : theme.colors.text}
29
+ color={iconColor}
30
+ iconColor = {iconColor}
29
31
  style = {flattenedStyle}
30
32
  Component={React.isComponent(Component)?Component:IconButton}
31
33
  ref = {ref}
@@ -24,6 +24,7 @@ const IconButtonComponent = ({
24
24
  containerProps,
25
25
  style,
26
26
  testID,
27
+ color,
27
28
  ...rest
28
29
  }) => {
29
30
  const IconComponent = animated ? CrossFadeIcon : IconButton;
@@ -31,11 +32,11 @@ const IconButtonComponent = ({
31
32
  containerProps = defaultObj(containerProps);
32
33
  const containerStyle = StyleSheet.flatten(containerProps.style) || {};
33
34
  const backgroundColor = Colors.isValid(containerColor)? containerColor : Colors.isValid(containerStyle.color) ? containerStyle.color : undefined;
34
- const iconColor = Colors.isValid(customIconColor)? customIconColor : theme.colors.text;
35
+ const iconColor = Colors.isValid(customIconColor)? customIconColor : Colors.isValid(color)? color : theme.colors.text;
35
36
  const borderColor = theme.colors.outline || theme.colors.divider;
36
37
  const rippleColor = Colors.setAlpha(iconColor,0.32);
37
38
  const buttonSize = size * 1.5;
38
-
39
+ console.log(iconColor, " is conndddd ",color,rest);
39
40
  const borderStyles = {
40
41
  borderWidth: 0,
41
42
  borderRadius: buttonSize / 2,
@@ -47,18 +47,9 @@ class _Menu extends AppComponent {
47
47
  statusBarHeight: APPROX_STATUSBAR_HEIGHT,
48
48
  overlayAccessibilityLabel: 'Close menu',
49
49
  };
50
-
51
- static getDerivedStateFromProps1(nextProps, prevState) {
52
- if (nextProps.visible && !prevState.rendered) {
53
- return { rendered: true };
54
- }
55
-
56
- return null;
57
- }
58
50
  constructor(props){
59
51
  super(props);
60
52
  extendObj(this.state,{
61
- rendered: this.props.visible,
62
53
  top: 0,
63
54
  left: 0,
64
55
  menuLayout: { width: 0, height: 0 },
@@ -78,17 +69,13 @@ class _Menu extends AppComponent {
78
69
  componentWillUnmount() {
79
70
  super.componentWillUnmount();
80
71
  this.removeListeners();
72
+ this.menu = null;
73
+ this.anchor = null;
81
74
  }
82
75
 
83
76
  anchor = null;
84
- menu = null;
85
77
  backHandlerSubscription;
86
78
 
87
- isCoordinate = (anchor) =>
88
- !React.isValidElement(anchor) &&
89
- typeof anchor?.x === 'number' &&
90
- typeof anchor?.y === 'number';
91
-
92
79
  measureMenuLayout = () =>
93
80
  new Promise((resolve) => {
94
81
  if (this.menu) {
@@ -100,12 +87,6 @@ class _Menu extends AppComponent {
100
87
 
101
88
  measureAnchorLayout = () =>
102
89
  new Promise((resolve) => {
103
- const { anchor } = this.props;
104
- if (this.isCoordinate(anchor)) {
105
- resolve({ x: anchor.x, y: anchor.y, width: 0, height: 0 });
106
- return;
107
- }
108
-
109
90
  if (this.anchor) {
110
91
  this.anchor.measureInWindow((x, y, width, height) => {
111
92
  resolve({ x, y, width, height });
@@ -143,9 +124,11 @@ class _Menu extends AppComponent {
143
124
  };
144
125
 
145
126
  handleDismiss = () => {
146
- if (this.props.visible) {
147
- this.props.onDismiss();
148
- }
127
+ this.hide(()=>{
128
+ if (this.props.visible) {
129
+ this.props.onDismiss();
130
+ }
131
+ });
149
132
  return true;
150
133
  };
151
134
 
@@ -198,8 +181,8 @@ class _Menu extends AppComponent {
198
181
  !windowLayout.height ||
199
182
  !menuLayout.width ||
200
183
  !menuLayout.height ||
201
- (!anchorLayout.width && !this.isCoordinate(this.props.anchor)) ||
202
- (!anchorLayout.height && !this.isCoordinate(this.props.anchor))
184
+ (!anchorLayout.width) ||
185
+ (!anchorLayout.height)
203
186
  ) {
204
187
  requestAnimationFrame(this.show);
205
188
  return;
@@ -244,7 +227,7 @@ class _Menu extends AppComponent {
244
227
  );
245
228
  };
246
229
 
247
- hide = () => {
230
+ hide = (cb) => {
248
231
  this.removeListeners();
249
232
  if(!this._isMounted()) return;
250
233
  const animation = theme.animation;
@@ -255,7 +238,7 @@ class _Menu extends AppComponent {
255
238
  useNativeDriver: true,
256
239
  }).start(({ finished }) => {
257
240
  if (finished) {
258
- this.setState({ menuLayout: { width: 0, height: 0 }, rendered: false });
241
+ this.setState({ menuLayout: { width: 0, height: 0 }},(e)=>{if(typeof cb ==='function') cb();});
259
242
  this.state.scaleAnimation.setValue({ x: 0, y: 0 });
260
243
  this.focusFirstDOMNode(this.anchor);
261
244
  }
@@ -283,8 +266,8 @@ class _Menu extends AppComponent {
283
266
  opacityAnimation,
284
267
  scaleAnimation,
285
268
  } = this.state;
286
- const rendered = visible;
287
269
  const minWidth = defaultDecimal(customMinWidth);
270
+ const rendered = this.props.visible;
288
271
  let { left, top } = this.state;
289
272
 
290
273
  // I don't know why but on Android measure function is wrong by 24
@@ -458,7 +441,7 @@ class _Menu extends AppComponent {
458
441
 
459
442
  //- (sameWidth ? anchorLayout.height : 0)
460
443
  const positionStyle = {
461
- top: this.isCoordinate(anchor) ? top : top + additionalVerticalValue,
444
+ top: top + additionalVerticalValue,
462
445
  ...(I18nManager.isRTL ? { right: left } : { left }),
463
446
  };
464
447
  if(sameWidth){
@@ -474,8 +457,9 @@ class _Menu extends AppComponent {
474
457
  positionStyle.top = SCREEN_INDENT;
475
458
  }
476
459
  const maxMenuHeight = windowLayout.height - top - SCREEN_INDENT;
477
- const maxHeight = maxMenuHeight >=0 ? Math.max(Math.min(maxMenuHeight,menuLayout.height),150) : windowLayout.height - SCREEN_INDENT*2;
460
+ const maxHeight = maxMenuHeight >=0 ? Math.max(Math.max(maxMenuHeight,menuLayout.height),150) : windowLayout.height - SCREEN_INDENT*2;
478
461
  const contentContainerStyle = maxMenuHeight > SCREEN_INDENT ? {maxHeight} : undefined;
462
+ const hiddenStyle = !rendered ? {display:'none',width:0,opacity:0} : null;
479
463
  return (
480
464
  <View
481
465
  testID = {testID}
@@ -485,17 +469,18 @@ class _Menu extends AppComponent {
485
469
  collapsable={false}
486
470
  style = {{backgroundColor:'transparent'}}
487
471
  >
488
- {this.isCoordinate(anchor) ? null : anchor}
489
- {rendered ? (
472
+ {anchor}
473
+ {true ? (
490
474
  <Portal>
491
- <TouchableWithoutFeedback
475
+ {rendered ? <TouchableWithoutFeedback
492
476
  testID={testID+"_TouchableWithoutFeedBack"}
493
477
  accessibilityLabel={overlayAccessibilityLabel}
494
478
  accessibilityRole="button"
495
479
  onPress={onDismiss}
480
+ style = {[hiddenStyle]}
496
481
  >
497
482
  <View style={[StyleSheet.absoluteFill,{flex:1,backgroundColor:'transparent'}]} testID={testID+"_Backdrop"} />
498
- </TouchableWithoutFeedback>
483
+ </TouchableWithoutFeedback>:null}
499
484
  <View
500
485
  testID = {testID+"_ContentContainer"}
501
486
  ref={(ref) => {
@@ -503,11 +488,11 @@ class _Menu extends AppComponent {
503
488
  }}
504
489
  collapsable={false}
505
490
  accessibilityViewIsModal={visible}
506
- style={[styles.wrapper, positionStyle, style]}
491
+ style={[styles.wrapper, positionStyle, style,hiddenStyle]}
507
492
  pointerEvents={visible ? 'box-none' : 'none'}
508
493
  onAccessibilityEscape={onDismiss}
509
494
  >
510
- <Animated.View style={{ transform: positionTransforms }} testID={testID+"_Animated"}>
495
+ {rendered?<Animated.View style={{ transform: positionTransforms }} testID={testID+"_Animated"}>
511
496
  <Surface
512
497
  elevation = {5}
513
498
  testID= {testID+"_Content"}
@@ -525,7 +510,7 @@ class _Menu extends AppComponent {
525
510
  {((scrollableMenuHeight|| contentContainerStyle) && (<ScrollView contentContainerStyle={contentContainerStyle} testID={testID+"_ScrollView"}>{children}</ScrollView>
526
511
  )) || children}
527
512
  </Surface>
528
- </Animated.View>
513
+ </Animated.View> : null}
529
514
  </View>
530
515
  </Portal>
531
516
  ) : null}
@@ -73,7 +73,7 @@ const MenuComponent = React.forwardRef((props,ref)=>{
73
73
  console.error("unable to render menu, anchor not spécified for props",props);
74
74
  }
75
75
  const context = {openMenu,closeMenu,open:openMenu,close:closeMenu};
76
- React.setRef(ref,context);
76
+ //React.setRef(ref,context);
77
77
  if(typeof children =='function'){
78
78
  children = children({openMenu,closeMenu,context});
79
79
  }
@@ -81,8 +81,17 @@ const MenuComponent = React.forwardRef((props,ref)=>{
81
81
  return ()=>{
82
82
  React.setRef(ref,null);
83
83
  }
84
- },[])
85
- return <Menu {...menuProps} testID={testID} visible={visible} onDismiss={closeMenu} anchor={anchor}>
84
+ },[]);
85
+ return <Menu {...menuProps} ref={(el)=>{
86
+ if(el){
87
+ for(let i in context){
88
+ if(!(i in el)){
89
+ el[i] = context[i];
90
+ }
91
+ }
92
+ }
93
+ React.setRef(ref,el);
94
+ }} testID={testID} visible={visible} onDismiss={closeMenu} anchor={anchor}>
86
95
  {renderItems({...props,onPressItem,renderItem,openMenu,closeMenu})}
87
96
  {React.isValidElement(children)? children: null}
88
97
  </Menu>
@@ -7,7 +7,7 @@ import Expandable from "$ecomponents/Expandable";
7
7
  import {cursorPointer} from "$theme";
8
8
  import Item from "./Item";
9
9
 
10
- export const MIN_WIDTH = 160;
10
+ export const MIN_WIDTH = 180;
11
11
 
12
12
  export const renderItems = (props)=>{
13
13
  let _items = [];
@@ -4,7 +4,6 @@ import {
4
4
  StyleSheet,
5
5
  View,
6
6
  TouchableWithoutFeedback,
7
- Animated,
8
7
  } from 'react-native';
9
8
  import PropTypes from "prop-types";
10
9
  import theme,{StyleProp} from "$theme";
@@ -13,7 +13,6 @@ export const positions = {top:"top",right:"right",bottom:"bottom",left:"left"}
13
13
 
14
14
  const TooltipComponent = React.forwardRef((props,ref)=>{
15
15
  let {tooltipProps,position,Component,children,strictPosition,...rest} = props;
16
- rest = defaultObj(rest);
17
16
  tooltipProps = defaultObj(tooltipProps);
18
17
  Component = React.isComponent(tooltipProps.Component) ? tooltipProps.Component : React.isComponent(Component) ? Component : Label;
19
18
  delete tooltipProps.position;
@@ -1,360 +0,0 @@
1
- import {uniqid,defaultStr,defaultObj} from "$utils";
2
- import {addClassName, removeClassName} from "$utils/dom";
3
- import theme from "$theme";
4
- import {MAX_WIDTH} from "$ecomponents/Dialog/utils";
5
- import {Elevations} from "$ecomponents/Surface";
6
- import { StyleSheet } from "react-native";
7
- import {Dimensions} from "react-native";
8
- const domId = uniqid("alter-7-dom-id");
9
- (function (Alert7) {
10
-
11
- var _TYPE_DEFAULT = 0;
12
- var _TYPE_CONFIRM = 1;
13
- (function () {
14
- Alert7 = window.Alert7 = Alert7 || _getInitialClass();
15
- }());
16
-
17
- function _getInitialClass() {
18
-
19
- Alert7Class.TYPE_DEFAULT = _TYPE_DEFAULT;
20
- Alert7Class.TYPE_CONFIRM = _TYPE_CONFIRM;
21
- Alert7Class.alert = _staticAlert;
22
- Alert7Class.break = _staticBreak;
23
- _appendCSS();
24
- return Alert7Class;
25
-
26
- }
27
-
28
- function _staticAlert(_title, _message) {
29
-
30
- var _tempAlert = new Alert7Class();
31
- var _args = [].splice.call(arguments, 2);
32
- _tempAlert.setTitle(_title);
33
- _tempAlert.setMessage(_message);
34
- while ( _args.length ) _tempAlert.addAction(_args.shift(), _args.shift());
35
- _tempAlert.present();
36
- return _tempAlert;
37
-
38
- }
39
-
40
- function _staticBreak() {
41
-
42
- throw null;
43
-
44
- }
45
-
46
- function _appendCSS() {
47
- let maxWidth = MAX_WIDTH;
48
- const backgroundColor = theme.colors.surface+";",color=theme.colors.text+";";
49
- const {width:windowWidth} = Dimensions.get("window");
50
- if(typeof windowWidth <= maxWidth){
51
- maxWidth = windowWidth*90/100;
52
- }
53
- var _styleElement = document.getElementById(domId);
54
- if(!_styleElement){
55
- _styleElement = document.createElement("style");
56
- document.getElementsByTagName("head")[0].appendChild(_styleElement);
57
- }
58
- _styleElement.id = domId;
59
- _styleElement.innerHTML = "" +
60
- "#Alert7," +
61
- "#Alert7::after," +
62
- "#Alert7 .alert7-container {" +
63
- "vertical-align: middle;" +
64
- "}" +
65
- "" +
66
- "#Alert7 {" +
67
- "position: fixed;" +
68
- "top: 0;" +
69
- "bottom: 0;" +
70
- "left: 0;" +
71
- "right: 0;" +
72
- "z-index: 1001;" +
73
- "background-color: " +theme.colors.backdrop+";"+
74
- "text-align: center;" +
75
- "font-size: 16px;" +
76
- "-webkit-user-select: none;" +
77
- " -moz-user-select: none;" +
78
- " -ms-user-select: none;" +
79
- " user-select: none;" +
80
- "}" +
81
- "" +
82
- "#Alert7.alert7-confirm {" +
83
- "}" +
84
- "" +
85
- "#Alert7::after," +
86
- "#Alert7 .alert7-container {" +
87
- "display: inline-block;" +
88
- "}" +
89
- "" +
90
- "#Alert7::after {" +
91
- "height: 100%;" +
92
- "content: '';" +
93
- "}" +
94
- "#Alert7 .alert7-container {" +
95
- "min-width:240px;"+
96
- "max-width: "+maxWidth+(typeof maxWidth =='number'? "px":"")+";" +
97
- "width: auto;" +
98
- "box-sizing: border-box;" +
99
- "background-color:"+backgroundColor+
100
- "border-radius: 0px;" +
101
- "max-height: calc(100% - 64px);"+
102
- "overflow-y: auto;"+
103
- "color:"+color+
104
- "box-shadow:rgb(0 0 0 / 20%) 0px 11px 15px -7px, rgb(0 0 0 / 14%) 0px 24px 38px 3px, rgb(0 0 0 / 12%) 0px 9px 46px 8px"+
105
- "}" +
106
- "" +
107
- "#Alert7 .alert7-title," +
108
- "#Alert7 .alert7-message {" +
109
- "font-family: Roboto, Helvetica, Arial, sans-serif;"+
110
- "line-height: 1.6;"+
111
- "letter-spacing: 0.0075em;"+
112
- "padding:10px;"+
113
- "text-align:left;"+
114
- "}" +
115
- "" +
116
- "#Alert7 .alert7-title {" +
117
- "font-size: 1.1em;" +
118
- "font-weight: bolder;" +
119
- //"line-height: 2rem;" +
120
- "}" +
121
- "" +
122
- "#Alert7 .alert7-message {" +
123
- "padding-bottom: 14px;" +
124
- "font-size: 0.9em;" +
125
- "}" +
126
- "" +
127
- "#Alert7 .alert7-actions {" +
128
- "width:100%;"+
129
- "text-align:right;"+
130
- "padding-bottom:7px"+
131
- "}" +
132
- "" +
133
- "#Alert7 .alert7-actions button.alert7-action-item {" +
134
- "display: inline-block;"+
135
- "position: relative;"+
136
- "box-sizing: border-box;"+
137
- "-webkit-tap-highlight-color: transparent;"+
138
- "background-color: transparent;"+
139
- "outline: 0px;"+
140
- "border: 0px;"+
141
- "margin: 0px;"+
142
- "cursor: pointer;"+
143
- "user-select: none;"+
144
- "vertical-align: middle;"+
145
- "appearance: none;"+
146
- "text-decoration: none;"+
147
- "font-family: Roboto, Helvetica, Arial, sans-serif;"+
148
- "font-weight: 500;"+
149
- "font-size: 0.875rem;"+
150
- "line-height: 1.75;"+
151
- "letter-spacing: 0.02857em;"+
152
- "text-transform: uppercase;"+
153
- "min-width: 64px;"+
154
- "padding: 6px 8px;"+
155
- "margin-right:7px;"+
156
- "margin-bottom:4px;"+
157
- "border-radius: 4px;"+
158
- "transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, border-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms, color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;"+
159
- "}" +
160
- "" +
161
- "#Alert7.alert7-confirm .alert7-actions button.alert7-action-item:first-of-type:last-of-type {" +
162
- "width: 100%;" +
163
- "}" +
164
- "" +
165
- "#Alert7.alert7-confirm .alert7-actions button.alert7-action-item:nth-of-type(n+3) {" +
166
- "display: none;" +
167
- "}" +
168
- "@media only screen and (min-width: "+(MAX_WIDTH)+"px) {"+
169
- "#Alert7 .alert7-container {"+
170
- "max-width:"+(MAX_WIDTH-20)+"px!important;"+
171
- "}"+
172
- "}"+
173
- "@media only screen and (max-width: "+MAX_WIDTH+"px) {"+
174
- "#Alert7 .alert7-container {"+
175
- "max-width:90%!important;"+
176
- "}"+
177
- "}"+
178
- "";
179
- }
180
-
181
- function Alert7Class() {
182
-
183
- this.title = "";
184
- this.message = "";
185
- this.type = _TYPE_DEFAULT;
186
- this.actions = [];
187
- _createAlertElement(this);
188
-
189
- }
190
-
191
- function _createAlertElement(_self) {
192
-
193
- _self.instanceElement = document.createElement("div");
194
- _self.instanceElement.id = "Alert7";
195
- _self.alertElement = document.createElement("div");
196
- _self.alertElement.className = "alert7-container";
197
- _self.instanceElement.appendChild(_self.alertElement);
198
- _self.titleElement = document.createElement("div");
199
- _self.titleElement.className = "alert7-title";
200
- _self.alertElement.appendChild(_self.titleElement);
201
- _self.messageElement = document.createElement("div");
202
- _self.messageElement.className = "alert7-message";
203
- _self.alertElement.appendChild(_self.messageElement);
204
- _self.actionsElement = document.createElement("div");
205
- _self.actionsElement.className = "alert7-actions";
206
- _self.alertElement.appendChild(_self.actionsElement);
207
-
208
- }
209
-
210
- Alert7Class.prototype.setTitle = function (_text) {
211
-
212
- this.title = _text || "";
213
-
214
- };
215
-
216
- Alert7Class.prototype.setMessage = function (_text) {
217
- this.message = _text || "";
218
- };
219
-
220
- Alert7Class.prototype.setType = function (_enum) {
221
-
222
- this.type = _enum || _TYPE_DEFAULT;
223
-
224
- };
225
-
226
- Alert7Class.prototype.addAction = function (_text, _handler) {
227
-
228
- this.actions.push({
229
- text: _text,
230
- handler: _handler
231
- });
232
-
233
- };
234
-
235
- Alert7Class.prototype.present = function () {
236
- this.titleElement.innerText = this.titleElement.textContent = this.title;
237
- const isDark = theme.isDark();
238
- _appendCSS();
239
- removeClassName(this.titleElement,"alert7-title");
240
- if(typeof this.title =="string" && this.title.length){
241
- addClassName(this.titleElement,"alert7-title");
242
- this.titleElement.style.background = isDark?theme.colors.surface : theme.colors.primary;
243
- this.titleElement.style.color = isDark?theme.colors.surfaceText : theme.colors.primaryText;
244
- this.titleElement.style.borderBottom = "1px solid "+theme.colors.divider;
245
- }
246
- this.messageElement.innerHTML = this.messageElement.textContent = defaultStr(this.message).replaceAll("\n","</br>");
247
- switch ( this.type ) {
248
- case _TYPE_CONFIRM: this.instanceElement.classList.add("alert7-confirm");
249
- }
250
- if ( !this.actions.length ) this.actions.push({});
251
- _createActions(this);
252
- document.querySelector("body").appendChild(this.instanceElement);
253
-
254
- };
255
-
256
- Alert7Class.prototype.dismiss = function () {
257
-
258
- if ( !this.instanceElement.parentNode ) return;
259
- this.instanceElement.parentNode.removeChild(this.instanceElement);
260
-
261
- };
262
-
263
- function _createActions(_self) {
264
-
265
- var _actions = _self.actions;
266
- var _numOfAction = _actions.length;
267
- var _tempActionElement;
268
- var _datum;
269
- _self.actionsElement.innerHTML = "";
270
- while ( _numOfAction-- ) {
271
- _datum = _actions[_numOfAction];
272
- const button = _datum.text;
273
- if(typeof button =="text"){
274
- button = {text:button};
275
- } else button = defaultObj(button);
276
- const text = defaultStr(button.text,button.label);
277
- if(!text) _numOfAction--;
278
- _tempActionElement = document.createElement("button");
279
- _tempActionElement.className = "alert7-action-item";
280
- _tempActionElement.innerText = _tempActionElement.textContent = text;// _datum.text || "OK";
281
- const stylesInput = StyleSheet.flatten(button.style);
282
- const style = _tempActionElement.style;
283
- for(let i in stylesInput){
284
- if(style.hasOwnProperty(i)){
285
- style[i] = stylesInput[i];
286
- }
287
- }
288
- _tempActionElement.addEventListener("click", _onClick(_datum.handler), false);
289
- _self.actionsElement.insertBefore(_tempActionElement, _self.actionsElement.firstChild);
290
- }
291
-
292
- function _onClick(_handler) {
293
- return function () {
294
- try {
295
- if ( _handler ) _handler();
296
- _self.dismiss();
297
- } catch (_error) {}
298
- };
299
- }
300
-
301
- }
302
-
303
- }(window.Alert7));
304
-
305
- function escapeHTML(string) {
306
- let pre = document.createElement('pre');
307
- let text = document.createTextNode(string);
308
- pre.appendChild(text);
309
- return pre.innerHTML;
310
- }
311
-
312
- const Alert = {
313
- alert(title, message='', callbackOrButtons=[{text:'OK', onPress : (f) => f}]) {
314
- let alert = new Alert7();
315
- alert.setTitle(title);
316
- alert.setMessage(escapeHTML(message));
317
- if (typeof callbackOrButtons === 'function') {
318
- const callback = callbackOrButtons;
319
- alert.addAction('OK', callback);
320
- } else {
321
- const buttons = callbackOrButtons;
322
- buttons.forEach((button) => {
323
- alert.addAction(button, button.onPress || (f=>f));
324
- });
325
- if (buttons.length === 2) {
326
- alert.setType(Alert7.TYPE_CONFIRM);
327
- }
328
- }
329
- alert.present();
330
- },
331
-
332
- prompt(title, message='', callbackOrButtons=(f) => f, type='plain-text', defaultValue='') {
333
- const alertPromptId = uniqid('alert7-prompt-input')
334
- function getInputCallback(callback) {
335
- return () => {
336
- const text = document.getElementById(alertPromptId).value;
337
- return callback(text);
338
- };
339
- }
340
-
341
- let alert = new Alert7();
342
- alert.setTitle(title);
343
- const msg = `<br/><input type="${(type==='secure-text'||type==='login-password')?'password':'text'}" value="${defaultValue}" id=${alertPromptId} style="width: 100%; height: 18px; border: 1px solid #ccc;" />`;
344
- alert.setMessage(escapeHTML(message) + msg);
345
- if (typeof callbackOrButtons === 'function') {
346
- const callback = callbackOrButtons;
347
- alert.addAction('OK', getInputCallback(callback));
348
- } else {
349
- const buttons = callbackOrButtons;
350
- buttons.forEach((button) => {
351
- alert.addAction(button, getInputCallback(button.onPress || (f=>f)));
352
- });
353
- if (buttons.length === 2) {
354
- alert.setType(Alert7.TYPE_CONFIRM);
355
- }
356
- }
357
- alert.present();
358
- }
359
- };
360
- export default Alert;
@@ -1,2 +0,0 @@
1
- import { Alert as RNAlert} from "react-native";
2
- export default RNAlert;