Skip to content

Commit

Permalink
Added SafeAreaBox component
Browse files Browse the repository at this point in the history
  • Loading branch information
ntorionbearstudio committed Oct 21, 2023
1 parent fcfad34 commit 0e7aed1
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 0 deletions.
19 changes: 19 additions & 0 deletions example/src/components/SafeAreaBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import React from 'react';
import { Box, SafeAreaBox, Text } from 'react-native-ficus-ui';

const SafeAreaBoxComponent = () => {
return (
<SafeAreaBox bg="blue.100" h="100%">
<Box px="xl">
<Text fontSize="4xl">SafeAreaBox component</Text>
<Box flexDirection="row">
<Box h={40} w={40} mr="sm" bg="green.500" />
<Box h={40} w={40} mr="sm" bg="teal.500" />
<Box h={40} w={40} mr="sm" bg="yellow.500" />
</Box>
</Box>
</SafeAreaBox>
);
};

export default SafeAreaBoxComponent;
6 changes: 6 additions & 0 deletions example/src/items.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import RadioComponent from './components/Radio';
import ToastHook from './components/Toast';
import ModalComponent from './components/Modal';
import FlashListComponent from './components/FlashList';
import SafeAreaBoxComponent from './components/SafeAreaBox';

type ExampleComponentType = {
onScreenName: string;
Expand All @@ -36,6 +37,11 @@ export const components: ExampleComponentType[] = [
component: TextComponent,
},
{ navigationPath: 'Box', onScreenName: 'Box', component: BoxComponent },
{
navigationPath: 'SafeAreaBox',
onScreenName: 'SafeAreaBox',
component: SafeAreaBoxComponent,
},
{
navigationPath: 'Center',
onScreenName: 'Center',
Expand Down
2 changes: 2 additions & 0 deletions src/components/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
export { Box } from './box/box.component';
export { BoxProps } from './box/box.type';
export { SafeAreaBox } from './safeareabox/safeareabox.component';
export { SafeAreaBoxProps } from './safeareabox/safeareabox.type';
export { ScrollBox } from './scrollbox/scrollbox.component';
export { ScrollBoxProps } from './scrollbox/scrollbox.type';
export { Flex } from './flex/flex.component';
Expand Down
112 changes: 112 additions & 0 deletions src/components/safeareabox/safeareabox.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import * as React from 'react';
import { SafeAreaView } from 'react-native';

import { getStyle } from './safeareabox.style';
import type { SafeAreaBoxProps } from './safeareabox.type';
import { useTheme } from '../../theme/theme.hook';
import { useDefaultProps } from '../../utilities/useDefaultProps';

const SafeAreaBox: React.FunctionComponent<SafeAreaBoxProps> = (
incomingProps
) => {
const props = useDefaultProps('SafeAreaBox', incomingProps, {
bg: 'transparent',
flexDirection: 'column',
flexWrap: 'nowrap',
borderRadius: 'none',
shadow: 'none',
position: 'relative',
pointerEvents: 'auto',
borderStyle: 'solid',
});

const {
bg,
h,
w,
m,
mt,
mr,
mb,
ml,
ms,
p,
pr,
pt,
pb,
pl,
minH,
minW,
maxW,
maxH,
position,
style,
flexDirection,
direction,
borderRadius,
borderTopRadius,
borderTopLeftRadius,
borderTopRightRadius,
borderBottomLeftRadius,
borderBottomRightRadius,
borderLeftRadius,
borderRightRadius,
borderBottomRadius,
children,
alignItems,
align,
justifyContent,
justify,
borderColor,
borderBottomColor,
borderLeftColor,
borderTopColor,
borderRightColor,
borderWidth,
borderLeftWidth,
borderRightWidth,
borderBottomWidth,
borderTopWidth,
borderEndWidth,
flexWrap,
wrap,
flexGrow,
grow,
flexBasis,
basis,
flexShrink,
shrink,
shadow,
shadowColor,
opacity,
overflow,
top,
left,
right,
bottom,
zIndex,
...rest
} = props;
const { theme } = useTheme();
const computedStyle = getStyle(theme, props);

return (
<SafeAreaView style={computedStyle.box} {...rest}>
{children}
</SafeAreaView>
);
};

// SafeAreaBox.defaultProps = {
// bg: 'transparent',
// flexDirection: 'column',
// flexWrap: 'nowrap',
// borderRadius: 'none',
// shadow: 'none',
// shadowColor: 'gray900',
// position: 'relative',
// pointerEvents: 'auto',
// borderStyle: 'solid',
// };

export { SafeAreaBox };
29 changes: 29 additions & 0 deletions src/components/safeareabox/safeareabox.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { render, screen } from '@testing-library/react-native';

import { Text } from '../text/text.component';
import { SafeAreaBox } from './safeareabox.component';
import type { SafeAreaBoxProps } from './safeareabox.type';
import { ThemeProvider } from '../../theme/theme.provider';

jest.mock('react-native-toast-message', () => 'Toast');

describe('SafeAreaBox component', () => {
const TestSafeAreaBox: React.FC<SafeAreaBoxProps> = (props) => (
<ThemeProvider>
<SafeAreaBox {...props} />
</ThemeProvider>
);

it('should render component passed to children', () => {
render(
<TestSafeAreaBox>
<Text>I love Ficus UI (forked from Magnus UI)</Text>
</TestSafeAreaBox>
);

expect(
screen.getByText('I love Ficus UI (forked from Magnus UI)')
).toBeTruthy();
});
});
67 changes: 67 additions & 0 deletions src/components/safeareabox/safeareabox.style.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { StyleSheet } from 'react-native';

import {
createShadowStyles,
createPositionStyle,
createSpacingStyles,
createBorderWidthStyles,
createBorderColorStyles,
createBorderRadiusStyles,
getThemeColor,
} from '../../theme/theme.service';
import type { SafeAreaBoxProps } from './safeareabox.type';
import type { ThemeType } from '../../theme/type';

/**
* computed style
*
* @param theme
* @param props
*/
export const getStyle = (theme: ThemeType, props: SafeAreaBoxProps) => {
const computedStyle: any = {};

computedStyle.box = {
flexDirection: props.direction ? props.direction : props.flexDirection,
flexWrap: props.wrap ? props.wrap : props.flexWrap,
alignItems: props.align ? props.align : props.alignItems,
justifyContent: props.justify ? props.justify : props.justifyContent,
flexBasis: props.basis ? props.basis : props.flexBasis,
flexGrow: props.grow ? props.grow : props.flexGrow,
flexShrink: props.shrink ? props.shrink : props.flexShrink,
height: props.h,
width: props.w,
minWidth: props.minW,
minHeight: props.minH,
alignSelf: props.alignSelf,
maxWidth: props.maxW,
maxHeight: props.maxH,
opacity: props.opacity,
overflow: props.overflow || 'hidden',
zIndex: props.zIndex,
borderStyle: props.borderStyle,
backgroundColor: getThemeColor(theme.colors, props.bg),
flex: props.flex,
...createPositionStyle(props),
...createShadowStyles(props, theme),
...createBorderWidthStyles(props),
...createSpacingStyles(props, theme.spacing),
...createBorderColorStyles(props, theme.colors),
...createBorderRadiusStyles(props, theme.borderRadius),
};

computedStyle.image = {
...createBorderRadiusStyles(props, theme.borderRadius),
};

// merging custom style props to computed style
if (props.style) {
computedStyle.box = {
...computedStyle.box,
// @ts-ignore
...props.style,
};
}

return StyleSheet.create(computedStyle);
};
31 changes: 31 additions & 0 deletions src/components/safeareabox/safeareabox.type.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import type { ViewProps as RNViewProps } from 'react-native';

import type {
BorderPropsType,
SpacingPropsType,
BorderRadiusPropsType,
ShadowPropsType,
DimensionPropsType,
BackgroundPropsType,
FlexPropsType,
PositionPropsType,
ZIndexPropsType,
OverflowPropsType,
OpacityPropsType,
VariantPropsType,
} from '../../types';

export interface SafeAreaBoxProps
extends RNViewProps,
BorderPropsType,
SpacingPropsType,
BorderRadiusPropsType,
ShadowPropsType,
DimensionPropsType,
BackgroundPropsType,
FlexPropsType,
PositionPropsType,
ZIndexPropsType,
OverflowPropsType,
OpacityPropsType,
VariantPropsType {}
2 changes: 2 additions & 0 deletions src/theme/type.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { TextProps } from 'components/text/text.type';
import type { ThemeProps, VariantType } from '../types';
import type { BoxProps } from 'components/box/box.type';
import type { SafeAreaBoxProps } from 'components/safeareabox/safeareabox.type';
import type { StackProps } from 'components/stack/stack.type';
import type { FlexProps } from 'components/flex/flex.type';
import type { CenterProps } from 'components/center/center.type';
Expand Down Expand Up @@ -46,6 +47,7 @@ export interface ThemeType {
components?: {
Text?: VariantType<TextProps>;
Box?: VariantType<BoxProps>;
SafeAreaBox?: VariantType<SafeAreaBoxProps>;
Flex?: VariantType<FlexProps>;
Center?: VariantType<CenterProps>;
ScrollBox?: VariantType<ScrollBoxProps>;
Expand Down

0 comments on commit 0e7aed1

Please sign in to comment.