react-native-ui-lib
Version:
[](https://stand-with-ukraine.pp.ua)
80 lines • 3.9 kB
JavaScript
import React, { useEffect, useMemo } from 'react';
import { StyleSheet } from 'react-native';
import { asBaseComponent } from "../../commons/new";
import { LogService } from "../../services";
import { Colors, Shadows } from "../../style";
import Button from "../button";
import ScreenFooter, { ScreenFooterLayouts, ScreenFooterBackgrounds, KeyboardBehavior, ItemsFit } from "../screenFooter";
export let FloatingButtonLayouts = /*#__PURE__*/function (FloatingButtonLayouts) {
FloatingButtonLayouts["VERTICAL"] = "Vertical";
FloatingButtonLayouts["HORIZONTAL"] = "Horizontal";
return FloatingButtonLayouts;
}({});
/**
* @description: Hovering button with gradient background, backed by ScreenFooter
* @modifiers: margin, background, color
* @example: https://github.com/wix/react-native-ui-lib/blob/master/demo/src/screens/componentScreens/FloatingButtonScreen.tsx
* @gif: https://github.com/wix/react-native-ui-lib/blob/master/demo/showcase/FloatingButton/FloatingButton.gif?raw=true
*/
const FloatingButton = props => {
const {
visible = false,
button,
secondaryButton,
bottomMargin,
fullWidth,
buttonLayout = FloatingButtonLayouts.VERTICAL,
duration = 300,
withoutAnimation,
hideBackgroundOverlay,
hoisted = true,
testID
} = props;
useEffect(() => {
// eslint-disable-next-line max-len
LogService.warn('RNUILib FloatingButton now uses ScreenFooter internally, which requires a SafeAreaProvider. If you experience safe area issues, please wrap your app (or the relevant screen) with <SafeAreaProvider>.');
}, []);
const footerContentContainerStyle = useMemo(() => {
if (bottomMargin !== undefined) {
return {
paddingBottom: bottomMargin
};
}
return undefined;
}, [bottomMargin]);
const isSecondaryOnly = !!secondaryButton && !button;
const isHorizontal = buttonLayout === FloatingButtonLayouts.HORIZONTAL || isSecondaryOnly;
if (!button && !secondaryButton) {
return null;
}
const renderPrimaryButton = () => {
if (!button) {
return null;
}
const shadowStyle = !button.outline && !button.link ? styles.shadow : undefined;
const shouldFlex = isHorizontal && !!secondaryButton || fullWidth && isHorizontal;
return <Button key="primary" size={Button.sizes.large} flex={!!shouldFlex} style={shadowStyle} testID={testID ? `${testID}.button` : undefined} {...button} />;
};
const renderSecondaryButton = () => {
if (!secondaryButton) {
return null;
}
const shouldFlex = isHorizontal && !!button || fullWidth && isSecondaryOnly;
const bgColor = secondaryButton.backgroundColor || Colors.$backgroundDefault;
return <Button key="secondary" outline={isHorizontal} link={!isHorizontal} flex={shouldFlex} size={Button.sizes.large} testID={testID ? `${testID}.secondaryButton` : undefined} {...secondaryButton} style={isHorizontal ? [styles.shadow, {
backgroundColor: bgColor
}] : undefined} enableShadow={false} />;
};
const children = isHorizontal ? [renderSecondaryButton(), renderPrimaryButton()] : [renderPrimaryButton(), renderSecondaryButton()];
return <ScreenFooter visible={visible} layout={isHorizontal ? ScreenFooterLayouts.HORIZONTAL : ScreenFooterLayouts.VERTICAL} backgroundType={hideBackgroundOverlay ? ScreenFooterBackgrounds.TRANSPARENT : ScreenFooterBackgrounds.FADING} keyboardBehavior={hoisted ? KeyboardBehavior.HOISTED : KeyboardBehavior.STICKY} animationDuration={withoutAnimation ? 0 : duration} itemsFit={fullWidth ? ItemsFit.STRETCH : undefined} contentContainerStyle={footerContentContainerStyle} testID={testID}>
{children}
</ScreenFooter>;
};
FloatingButton.displayName = 'FloatingButton';
FloatingButton.floatingButtonLayouts = FloatingButtonLayouts;
const styles = StyleSheet.create({
shadow: {
...Shadows.sh20.bottom
}
});
export default asBaseComponent(FloatingButton);