react-native-ui-lib 8.4.3-snapshot.7934 → 8.4.3-snapshot.7939

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ui-lib",
3
- "version": "8.4.3-snapshot.7934",
3
+ "version": "8.4.3-snapshot.7939",
4
4
  "main": "src/index.js",
5
5
  "types": "src/index.d.ts",
6
6
  "author": "Ethan Sharabi <ethan.shar@gmail.com>",
@@ -5,7 +5,7 @@ export declare enum FloatingButtonLayouts {
5
5
  VERTICAL = "Vertical",
6
6
  HORIZONTAL = "Horizontal"
7
7
  }
8
- export interface FloatingButtonProps extends Pick<ScreenFooterProps, 'isAndroidEdgeToEdge'> {
8
+ export interface FloatingButtonProps extends Pick<ScreenFooterProps, 'isAndroidEdgeToEdge' | 'animationType'> {
9
9
  /**
10
10
  * Whether the button is visible
11
11
  */
@@ -29,6 +29,7 @@ const FloatingButton = props => {
29
29
  hideBackgroundOverlay,
30
30
  hoisted = Constants.isAndroid,
31
31
  isAndroidEdgeToEdge,
32
+ animationType,
32
33
  testID
33
34
  } = props;
34
35
  useEffect(() => {
@@ -70,7 +71,7 @@ const FloatingButton = props => {
70
71
  }] : undefined} enableShadow={false} />;
71
72
  };
72
73
  const children = isHorizontal ? [renderSecondaryButton(), renderPrimaryButton()] : [renderPrimaryButton(), renderSecondaryButton()];
73
- return <ScreenFooter visible={visible} layout={isHorizontal ? ScreenFooterLayouts.HORIZONTAL : ScreenFooterLayouts.VERTICAL} backgroundType={hideBackgroundOverlay ? ScreenFooterBackgrounds.TRANSPARENT : ScreenFooterBackgrounds.FADING} keyboardBehavior={hoisted ? KeyboardBehavior.HOISTED : KeyboardBehavior.STICKY} isAndroidEdgeToEdge={isAndroidEdgeToEdge} animationDuration={withoutAnimation ? 0 : duration} itemsFit={fullWidth ? ItemsFit.STRETCH : undefined} contentContainerStyle={footerContentContainerStyle} testID={testID}>
74
+ return <ScreenFooter visible={visible} layout={isHorizontal ? ScreenFooterLayouts.HORIZONTAL : ScreenFooterLayouts.VERTICAL} backgroundType={hideBackgroundOverlay ? ScreenFooterBackgrounds.TRANSPARENT : ScreenFooterBackgrounds.FADING} keyboardBehavior={hoisted ? KeyboardBehavior.HOISTED : KeyboardBehavior.STICKY} isAndroidEdgeToEdge={isAndroidEdgeToEdge} animationDuration={withoutAnimation ? 0 : duration} animationType={animationType} itemsFit={fullWidth ? ItemsFit.STRETCH : undefined} contentContainerStyle={footerContentContainerStyle} testID={testID}>
74
75
  {children}
75
76
  </ScreenFooter>;
76
77
  };
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
- import { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterShadow } from './types';
3
- export { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterShadow };
2
+ import { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterAnimationTypeProp, ScreenFooterShadow } from './types';
3
+ export { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterAnimationTypeProp, ScreenFooterShadow };
4
4
  declare const _default: React.ForwardRefExoticComponent<ScreenFooterProps & React.RefAttributes<any>> & {
5
5
  (props: ScreenFooterProps): React.JSX.Element;
6
6
  displayName: string;
@@ -1,6 +1,6 @@
1
- import React, { useCallback, useEffect, useMemo, useState } from 'react';
1
+ import React, { useCallback, useMemo } from 'react';
2
2
  import { StyleSheet } from 'react-native';
3
- import Animated, { useAnimatedKeyboard, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
3
+ import Animated from 'react-native-reanimated';
4
4
  import { Keyboard } from 'uilib-native';
5
5
  import { SafeAreaContextPackage } from "../../optionalDependencies";
6
6
  import View from "../view";
@@ -9,9 +9,9 @@ import Assets from "../../assets";
9
9
  import { Colors, Shadows, Spacings } from "../../style";
10
10
  import { asBaseComponent, Constants } from "../../commons/new";
11
11
  import { useKeyboardHeight } from "../../hooks";
12
- import { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterShadow } from "./types";
13
- export { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterShadow };
14
- const androidVersion = Constants.getAndroidVersion();
12
+ import useAnimatedFooterStyle from "./useAnimatedFooterStyle";
13
+ import { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterAnimationTypeProp, ScreenFooterShadow } from "./types";
14
+ export { ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterAnimationTypeProp, ScreenFooterShadow };
15
15
  const ScreenFooter = props => {
16
16
  const {
17
17
  testID,
@@ -25,45 +25,24 @@ const ScreenFooter = props => {
25
25
  itemWidth,
26
26
  horizontalItemsDistribution: distribution,
27
27
  visible = true,
28
- animationDuration = 200,
28
+ animationDuration,
29
+ animationType,
29
30
  shadow = ScreenFooterShadow.SH20,
30
31
  hideDivider = false,
31
- isAndroidEdgeToEdge = !!androidVersion && androidVersion >= 35 ? true : undefined,
32
+ isAndroidEdgeToEdge,
32
33
  containerStyle: containerStyleOverride,
33
34
  contentContainerStyle: contentContainerStyleOverride
34
35
  } = props;
35
- const withoutAnimation = animationDuration === 0;
36
- const keyboard = useAnimatedKeyboard({
37
- isNavigationBarTranslucentAndroid: isAndroidEdgeToEdge,
38
- isStatusBarTranslucentAndroid: isAndroidEdgeToEdge
39
- });
40
- const [height, setHeight] = useState(0);
41
- const visibilityTranslateY = useSharedValue(0);
42
-
43
- // Update visibility translation when visible or height changes
44
- useEffect(() => {
45
- visibilityTranslateY.value = withTiming(visible ? 0 : height, {
46
- duration: animationDuration
47
- });
48
- }, [visible, height, animationDuration, visibilityTranslateY]);
49
-
50
- // Animated style for STICKY behavior (counters Android system offset + visibility)
51
- const stickyAnimatedStyle = useAnimatedStyle(() => {
52
- const counterSystemOffset = Constants.isAndroid ? keyboard.height.value : 0;
53
- return {
54
- transform: [{
55
- translateY: counterSystemOffset + visibilityTranslateY.value
56
- }]
57
- };
58
- });
59
-
60
- // Animated style for HOISTED behavior (visibility only, keyboard handled by KeyboardAccessoryView)
61
- const hoistedAnimatedStyle = useAnimatedStyle(() => {
62
- return {
63
- transform: [{
64
- translateY: visibilityTranslateY.value
65
- }]
66
- };
36
+ const {
37
+ containerStyle,
38
+ setHeight
39
+ } = useAnimatedFooterStyle({
40
+ animationDuration,
41
+ animationType,
42
+ keyboardBehavior,
43
+ visible,
44
+ isAndroidEdgeToEdge,
45
+ containerStyle: containerStyleOverride
67
46
  });
68
47
  const onLayout = useCallback(event => {
69
48
  setHeight(event.nativeEvent.layout.height);
@@ -164,13 +143,13 @@ const ScreenFooter = props => {
164
143
  maxWidth: '100%'
165
144
  };
166
145
  return <View key={index} style={fixedStyle}>
167
- {child}
168
- </View>;
146
+ {child}
147
+ </View>;
169
148
  }
170
149
  if (isHorizontal && React.isValidElement(child) && itemsFit === ItemsFit.STRETCH) {
171
150
  return <View flex row centerH key={index}>
172
- {child}
173
- </View>;
151
+ {child}
152
+ </View>;
174
153
  }
175
154
  return child;
176
155
  }, [itemsFit, itemWidth, isHorizontal]);
@@ -183,31 +162,19 @@ const ScreenFooter = props => {
183
162
  </View>
184
163
  </>;
185
164
  }, [renderBackground, testID, contentContainerStyle, childrenArray]);
186
- const Container = useMemo(() => {
187
- return withoutAnimation ? View : Animated.View;
188
- }, [withoutAnimation]);
189
- const containerStyle = useMemo(() => {
190
- return withoutAnimation ? [styles.container, containerStyleOverride] : [styles.container, hoistedAnimatedStyle, containerStyleOverride];
191
- // eslint-disable-next-line react-hooks/exhaustive-deps
192
- }, [withoutAnimation, containerStyleOverride]);
193
- if (keyboardBehavior === KeyboardBehavior.HOISTED) {
194
- return <Container style={containerStyle} pointerEvents={visible ? 'box-none' : 'none'}>
195
- <Keyboard.KeyboardAccessoryView renderContent={renderFooterContent} kbInputRef={undefined} scrollBehavior={Keyboard.KeyboardAccessoryView.scrollBehaviors.FIXED_OFFSET} useSafeArea={false} manageScrollView={false} revealKeyboardInteractive onHeightChanged={setHeight} />
196
- </Container>;
197
- }
198
- return <Animated.View testID={testID} onLayout={onLayout} style={[styles.container, stickyAnimatedStyle, containerStyleOverride]}>
199
- {renderFooterContent()}
165
+ const renderKeyboardAwareFooter = useCallback(() => {
166
+ if (keyboardBehavior === 'hoisted') {
167
+ return <Keyboard.KeyboardAccessoryView renderContent={renderFooterContent} kbInputRef={undefined} scrollBehavior={Keyboard.KeyboardAccessoryView.scrollBehaviors.FIXED_OFFSET} useSafeArea={false} manageScrollView={false} revealKeyboardInteractive onHeightChanged={setHeight} />;
168
+ } else {
169
+ return renderFooterContent();
170
+ }
171
+ }, [keyboardBehavior, renderFooterContent]);
172
+ return <Animated.View testID={testID} style={containerStyle} onLayout={keyboardBehavior === 'hoisted' ? undefined : onLayout} pointerEvents={!visible ? 'none' : keyboardBehavior === 'hoisted' ? 'box-none' : 'auto'}>
173
+ {renderKeyboardAwareFooter()}
200
174
  </Animated.View>;
201
175
  };
202
176
  ScreenFooter.displayName = 'ScreenFooter';
203
177
  const styles = StyleSheet.create({
204
- container: {
205
- position: 'absolute',
206
- bottom: 0,
207
- left: 0,
208
- right: 0,
209
- zIndex: 50
210
- },
211
178
  contentContainer: {
212
179
  paddingTop: Spacings.s4,
213
180
  paddingHorizontal: Spacings.s5,
@@ -55,13 +55,19 @@
55
55
  {
56
56
  "name": "visible",
57
57
  "type": "boolean",
58
- "description": "If true, the footer is visible. If false, it slides down",
58
+ "description": "If true, the footer is visible. If false, the footer is hidden using the configured animation type",
59
59
  "default": "true"
60
60
  },
61
+ {
62
+ "name": "animationType",
63
+ "type": "ScreenFooterAnimationTypeProp",
64
+ "description": "The animation type for showing/hiding the footer [slide, fade, none]",
65
+ "default": "'slide'"
66
+ },
61
67
  {
62
68
  "name": "animationDuration",
63
69
  "type": "number",
64
- "description": "Duration of the show/hide animation in ms",
70
+ "description": "Duration of the show/hide animation in ms (sending 0 will disable the animation)",
65
71
  "default": "200"
66
72
  },
67
73
  {
@@ -32,7 +32,25 @@ export declare enum ScreenFooterShadow {
32
32
  SH20 = "sh20",
33
33
  SH30 = "sh30"
34
34
  }
35
- export interface ScreenFooterProps extends PropsWithChildren<{}> {
35
+ export declare enum ScreenFooterAnimation {
36
+ NONE = "none",
37
+ SLIDE = "slide",
38
+ FADE = "fade"
39
+ }
40
+ export type ScreenFooterAnimationTypeProp = ScreenFooterAnimation | `${ScreenFooterAnimation}`;
41
+ export interface AnimatedFooterStyleProps {
42
+ /**
43
+ * The type of animation to use when showing or hiding the footer.
44
+ * @default 'slide'
45
+ */
46
+ animationType?: ScreenFooterAnimationTypeProp;
47
+ /**
48
+ * Duration of the show/hide animation in ms (sending 0 will disable the animation).
49
+ * @default 200
50
+ */
51
+ animationDuration?: number;
52
+ }
53
+ export interface ScreenFooterProps extends AnimatedFooterStyleProps, PropsWithChildren<{}> {
36
54
  /**
37
55
  * Used as testing identifier
38
56
  */
@@ -78,11 +96,6 @@ export interface ScreenFooterProps extends PropsWithChildren<{}> {
78
96
  * If true, the footer is visible. If false, it slides down.
79
97
  */
80
98
  visible?: boolean;
81
- /**
82
- * Duration of the show/hide animation in ms.
83
- * @default 200
84
- */
85
- animationDuration?: number;
86
99
  /**
87
100
  * If true, the footer will respect the safe area (add bottom padding)
88
101
  */
@@ -36,4 +36,10 @@ export let ScreenFooterShadow = /*#__PURE__*/function (ScreenFooterShadow) {
36
36
  ScreenFooterShadow["SH20"] = "sh20";
37
37
  ScreenFooterShadow["SH30"] = "sh30";
38
38
  return ScreenFooterShadow;
39
+ }({});
40
+ export let ScreenFooterAnimation = /*#__PURE__*/function (ScreenFooterAnimation) {
41
+ ScreenFooterAnimation["NONE"] = "none";
42
+ ScreenFooterAnimation["SLIDE"] = "slide";
43
+ ScreenFooterAnimation["FADE"] = "fade";
44
+ return ScreenFooterAnimation;
39
45
  }({});
@@ -0,0 +1,14 @@
1
+ /// <reference types="react" />
2
+ import { ViewStyle } from 'react-native';
3
+ import { AnimatedFooterStyleProps, ScreenFooterProps } from './types';
4
+ declare const useAnimatedFooterStyle: (props: AnimatedFooterStyleProps & Pick<ScreenFooterProps, 'keyboardBehavior' | 'visible' | 'isAndroidEdgeToEdge' | 'containerStyle'>) => {
5
+ containerStyle: (import("react-native").StyleProp<ViewStyle> | {
6
+ position: "absolute";
7
+ bottom: number;
8
+ left: number;
9
+ right: number;
10
+ zIndex: number;
11
+ })[];
12
+ setHeight: import("react").Dispatch<import("react").SetStateAction<number>>;
13
+ };
14
+ export default useAnimatedFooterStyle;
@@ -0,0 +1,72 @@
1
+ import { useAnimatedKeyboard, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
2
+ import { StyleSheet } from 'react-native';
3
+ import { Constants } from "../../commons/new";
4
+ import { useEffect, useMemo, useState } from 'react';
5
+ const androidVersion = Constants.getAndroidVersion();
6
+ const useAnimatedFooterStyle = props => {
7
+ const {
8
+ animationType: animationTypeProp = 'slide',
9
+ animationDuration: animationDurationProp = 200,
10
+ keyboardBehavior,
11
+ visible,
12
+ isAndroidEdgeToEdge = !!androidVersion && androidVersion >= 35 ? true : undefined,
13
+ containerStyle: containerStyleOverride
14
+ } = props;
15
+ const animationType = animationDurationProp === 0 ? 'none' : animationTypeProp;
16
+ const animationDuration = animationType === 'none' ? 0 : animationDurationProp;
17
+ const keyboard = useAnimatedKeyboard({
18
+ isNavigationBarTranslucentAndroid: isAndroidEdgeToEdge,
19
+ isStatusBarTranslucentAndroid: isAndroidEdgeToEdge
20
+ });
21
+ const [height, setHeight] = useState(0);
22
+ const animatedValue = useSharedValue(animationType === 'fade' && visible ? 1 : 0);
23
+ useEffect(() => {
24
+ if (animationType === 'slide') {
25
+ animatedValue.value = withTiming(visible ? 0 : height, {
26
+ duration: animationDuration
27
+ });
28
+ } else {
29
+ animatedValue.value = withTiming(visible ? 1 : 0, {
30
+ duration: animationDuration
31
+ });
32
+ }
33
+ }, [visible, height, animationDuration, animatedValue, animationType]);
34
+ const animatedStyle = useAnimatedStyle(() => {
35
+ let style = {};
36
+ let translateY = 0;
37
+ if (animationType === 'slide') {
38
+ translateY = animatedValue.value;
39
+ } else {
40
+ style = {
41
+ opacity: animatedValue.value
42
+ };
43
+ }
44
+ if (keyboardBehavior === 'sticky' && Constants.isAndroid) {
45
+ translateY += keyboard.height.value;
46
+ }
47
+ if (animationType === 'slide' || translateY !== 0) {
48
+ style.transform = [{
49
+ translateY
50
+ }];
51
+ }
52
+ return style;
53
+ });
54
+ const containerStyle = useMemo(() => {
55
+ return [styles.container, animatedStyle, containerStyleOverride];
56
+ // eslint-disable-next-line react-hooks/exhaustive-deps
57
+ }, [containerStyleOverride]);
58
+ return {
59
+ containerStyle,
60
+ setHeight
61
+ };
62
+ };
63
+ export default useAnimatedFooterStyle;
64
+ const styles = StyleSheet.create({
65
+ container: {
66
+ position: 'absolute',
67
+ bottom: 0,
68
+ left: 0,
69
+ right: 0,
70
+ zIndex: 50
71
+ }
72
+ });
package/src/index.d.ts CHANGED
@@ -38,7 +38,7 @@ export { default as ExpandableSection, ExpandableSectionProps } from './componen
38
38
  export { default as Fader, FaderProps, FaderPosition } from './components/fader';
39
39
  export { default as FeatureHighlight, FeatureHighlightProps } from './components/featureHighlight';
40
40
  export { default as FloatingButton, FloatingButtonProps, FloatingButtonLayouts } from './components/floatingButton';
41
- export { default as ScreenFooter, ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterShadow } from './components/screenFooter';
41
+ export { default as ScreenFooter, ScreenFooterProps, ScreenFooterLayouts, ScreenFooterBackgrounds, FooterAlignment, HorizontalItemsDistribution, ItemsFit, KeyboardBehavior, ScreenFooterAnimationTypeProp, ScreenFooterShadow } from './components/screenFooter';
42
42
  export { default as Gradient, GradientProps, GradientTypes } from './components/gradient';
43
43
  export { default as Slider } from './components/slider';
44
44
  export { default as GradientSlider } from './components/slider/GradientSlider';
package/src/index.js CHANGED
@@ -109,6 +109,7 @@ var _exportNames = {
109
109
  HorizontalItemsDistribution: true,
110
110
  ItemsFit: true,
111
111
  KeyboardBehavior: true,
112
+ ScreenFooterAnimationTypeProp: true,
112
113
  ScreenFooterShadow: true,
113
114
  Gradient: true,
114
115
  GradientProps: true,
@@ -1199,6 +1200,12 @@ Object.defineProperty(exports, "ScreenFooter", {
1199
1200
  return _screenFooter().default;
1200
1201
  }
1201
1202
  });
1203
+ Object.defineProperty(exports, "ScreenFooterAnimationTypeProp", {
1204
+ enumerable: true,
1205
+ get: function () {
1206
+ return _screenFooter().ScreenFooterAnimationTypeProp;
1207
+ }
1208
+ });
1202
1209
  Object.defineProperty(exports, "ScreenFooterBackgrounds", {
1203
1210
  enumerable: true,
1204
1211
  get: function () {