Skip to content

Commit

Permalink
feat: update Onboarding screens for easier customization (#2462)
Browse files Browse the repository at this point in the history
* feat: named PhoneOutline for overrides and adding fill prop

* feat: do not display the dot container if there is only 1 slide

* chore: added more props to Intro screen for overriding

* chore: added name for children container

* feat: adds size to animated app icon, positioning options, and more styles to intro slide

* fix: fixed an icon override that was not working

* chore: add size to props validation

* fix: change size to appIconSize to be more expressive

* fix: changed items to listItems and also added support for no items
  • Loading branch information
nlewis84 committed Apr 1, 2022
1 parent 8c79621 commit ca147fd
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 35 deletions.
Expand Up @@ -16,7 +16,7 @@ const RotatorContainer = styled({
position: 'absolute',
})(Animated.View);

const Rotator = ({ index }) => {
const Rotator = ({ index, size = 134 }) => {
const entering = () => {
'worklet';

Expand Down Expand Up @@ -44,23 +44,28 @@ const Rotator = ({ index }) => {

return (
<RotatorContainer entering={entering}>
<AppIcon size={134} />
<AppIcon size={size} />
</RotatorContainer>
);
};

Rotator.propTypes = {
index: PropTypes.number,
size: PropTypes.number,
};

const AnimatedAppIcon = () => {
const AnimatedAppIcon = ({ size }) => {
return (
<Container>
<Rotator index={2} />
<Rotator index={1} />
<Rotator index={0} />
<Rotator index={2} size={size} />
<Rotator index={1} size={size} />
<Rotator index={0} size={size} />
</Container>
);
};

AnimatedAppIcon.propTypes = {
size: PropTypes.number,
};

export default AnimatedAppIcon;
44 changes: 29 additions & 15 deletions packages/apollos-ui-onboarding/src/LandingSwiper/LandingSlide.js
Expand Up @@ -31,7 +31,10 @@ const PhoneContainer = styled(
'ui-onboarding.LandingSwiper.LandingSlide.PhoneContainer'
)(View);

const ChildrenContainer = styled({ flex: 0.5 })(View);
const ChildrenContainer = styled(
() => ({ flex: 0.5 }),
'ui-onboarding.LandingSwiper.LandingSlide.ChildrenContainer'
)(View);

const PhoneMask = withTheme(({ theme }) => ({
style: StyleSheet.absoluteFill,
Expand Down Expand Up @@ -77,8 +80,16 @@ const PositionedSharedElement = styled(({ location = 'top' }) => ({
position: 'absolute',
left: 0,
right: 0,
// eslint-disable-next-line no-nested-ternary
top: location === 'top' ? '15%' : location === 'centered' ? '50%' : undefined,
top:
// eslint-disable-next-line no-nested-ternary
location === 'top'
? '15%'
: // eslint-disable-next-line no-nested-ternary
location === 'centered'
? '50%'
: location === 'top-mid'
? '20%'
: undefined,
bottom: location === 'bottom' ? '5%' : undefined,
}))(SharedElement);

Expand All @@ -105,17 +116,20 @@ const LandingSlide = ({
</PhoneContainer>
<ChildrenContainer>{children}</ChildrenContainer>
<SharedElement id="next-button">
<DotContainer>
{Array.from(Array(totalSlides)).map((_, i) =>
i === index ? (
// eslint-disable-next-line react/no-array-index-key
<PaginationDotActive key={i} />
) : (
// eslint-disable-next-line react/no-array-index-key
<PaginationDot key={i} />
)
)}
</DotContainer>
{Array.from(Array(totalSlides)).length > 1 ? (
// Don't show the dot container if there is only one slide
<DotContainer>
{Array.from(Array(totalSlides)).map((_, i) =>
i === index ? (
// eslint-disable-next-line react/no-array-index-key
<PaginationDotActive key={i} />
) : (
// eslint-disable-next-line react/no-array-index-key
<PaginationDot key={i} />
)
)}
</DotContainer>
) : null}
<ButtonContainer>
<PaddedView>
<PrimaryButton onPress={onContinue}>
Expand All @@ -133,7 +147,7 @@ LandingSlide.propTypes = {
index: PropTypes.number,
totalSlides: PropTypes.number,
calloutChildren: PropTypes.node,
calloutLocation: PropTypes.oneOf(['top', 'bottom', 'centered']),
calloutLocation: PropTypes.oneOf(['top', 'top-mid', 'bottom', 'centered']),
children: PropTypes.node,
onContinue: PropTypes.func,
primaryButtonText: PropTypes.string,
Expand Down
11 changes: 6 additions & 5 deletions packages/apollos-ui-onboarding/src/LandingSwiper/PhoneOutline.js
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import { StyleSheet, View } from 'react-native';
import PropTypes from 'prop-types';
import Svg, { Path } from 'react-native-svg';
import { styled, useTheme } from '@apollosproject/ui-kit';
import { named, styled, useTheme } from '@apollosproject/ui-kit';
import { SharedElement } from 'react-navigation-shared-element';

const OuterContainer = styled({
Expand All @@ -26,19 +26,19 @@ const styles = StyleSheet.create({
svg: { width: '100%', aspectRatio: 307 / 642 },
});

const PhoneOutline = ({ children }) => {
const PhoneOutline = ({ children, fill }) => {
const theme = useTheme();
return (
<OuterContainer>
<SharedElement id="phone-outline" style={StyleSheet.absoluteFill}>
<Svg style={styles.svg} viewBox="0 0 307 642">
<Path
d="M40.6133 0.807861H266.387C288.366 0.807861 306.184 18.6415 306.184 40.6404V601.36C306.184 623.358 288.366 641.192 266.387 641.192H40.6133C18.6338 641.192 0.815918 623.358 0.815918 601.36V40.6404C0.815918 18.6415 18.6338 0.807861 40.6133 0.807861ZM40.6133 9.99998C23.706 9.99998 9.99992 23.7182 9.99992 40.6404V601.36C9.99992 618.282 23.706 632 40.6133 632H266.387C283.294 632 297 618.282 297 601.36V40.6404C297 23.7182 283.294 9.99998 266.387 9.99998H40.6133Z"
fill={theme.colors.background.system}
fill={fill || theme.colors.background.system}
/>
<Path
d="M91.1553 33.7463H215.845C225.567 33.7463 233.447 25.8584 233.447 16.1281C233.447 16.1193 233.443 13.7457 233.443 13.2025C233.442 13.1288 233.454 13.0567 233.479 12.9874V12.9874C233.988 11.5879 235.17 10.518 236.622 10.1656L237.304 10H69.696L70.3786 10.1656C71.8234 10.5163 73.0125 11.598 73.5261 12.9874V12.9874C73.5514 13.0559 73.5577 13.1296 73.5575 13.2027L73.5526 16.0982C73.5526 25.8584 81.4336 33.7463 91.1553 33.7463Z"
fill={theme.colors.background.system}
fill={fill || theme.colors.background.system}
/>
</Svg>
</SharedElement>
Expand All @@ -51,6 +51,7 @@ const PhoneOutline = ({ children }) => {

PhoneOutline.propTypes = {
children: PropTypes.node,
fill: PropTypes.string,
};

export default PhoneOutline;
export default named('ui-onboarding.LandingSwiper.PhoneOutline')(PhoneOutline);
68 changes: 59 additions & 9 deletions packages/apollos-ui-onboarding/src/LandingSwiper/slides.js
Expand Up @@ -2,12 +2,14 @@ import React, { useCallback } from 'react';
import { View } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import {
H1,
H3,
H5,
styled,
Icon,
named,
ButtonLink,
useTheme,
} from '@apollosproject/ui-kit';

import LandingSlide from './LandingSlide';
Expand All @@ -29,11 +31,41 @@ const TextContainer = styled(({ theme }) => ({
alignSelf: 'center',
}))(View);

const CustomIntroTextContainer = styled(({ theme }) => ({
padding: theme.sizing.baseUnit * 2,
alignItems: 'flex-start',
textAlign: 'flex-start',
alignSelf: 'flex-start',
}))(View);

const ItemContainer = styled(({ theme }) => ({
display: 'flex',
flexDirection: 'row',
paddingTop: theme.sizing.baseUnit,
}))(View);

const Greeting = styled({ textAlign: 'left' })(H5);
const LeftSubTitle = styled(({ theme }) => ({
color: theme.colors.secondary,
textAlign: 'left',
}))(H1);
const Title = styled({ textAlign: 'center' })(H3);
const SubTitle = styled({ textAlign: 'center' })(H5);
const ItemText = styled(({ theme }) => ({
lineHeight: 32,
paddingLeft: theme.sizing.baseUnit,
}))(H5);

export const Intro = named('ui-onboarding.LandingSwiper.slides.Intro')(
({ onPressLogin, ...slideProps }) => {
({
onPressLogin,
listItems,
greeting,
appIconSize,
subtitle = 'Build a daily spiritual habit with others.',
...slideProps
}) => {
const theme = useTheme();
const navigation = useNavigation();
const onPress = useCallback(
() =>
Expand All @@ -47,8 +79,8 @@ export const Intro = named('ui-onboarding.LandingSwiper.slides.Intro')(
return (
<LandingSlide
screenChildren={<PlaceholderSpringboard />}
calloutChildren={<AnimatedAppIcon />}
calloutLocation="centered"
calloutChildren={<AnimatedAppIcon size={appIconSize} />}
calloutLocation={greeting ? 'top-mid' : 'centered'}
secondaryButtonChildren={
<H5 secondary padded centered>
Already have an account?{' '}
Expand All @@ -57,12 +89,30 @@ export const Intro = named('ui-onboarding.LandingSwiper.slides.Intro')(
}
{...slideProps}
>
<TextContainer>
<Icon name="brand-logo" size={60} />
<SubTitle secondary>
Build a daily spiritual habit with others.
</SubTitle>
</TextContainer>
{greeting ? (
<CustomIntroTextContainer>
<Greeting secondary>{greeting}</Greeting>
<LeftSubTitle primary>{subtitle}</LeftSubTitle>
{listItems?.map((item, i) => {
return (
// eslint-disable-next-line react/no-array-index-key
<ItemContainer key={i}>
<Icon
name={item.icon}
weight="fill"
fill={theme.colors.text.secondary}
/>
<ItemText primary>{item.text}</ItemText>
</ItemContainer>
);
})}
</CustomIntroTextContainer>
) : (
<TextContainer>
<Icon name="brand-logo" size={60} />
<SubTitle secondary>{subtitle}</SubTitle>
</TextContainer>
)}
</LandingSlide>
);
}
Expand Down

0 comments on commit ca147fd

Please sign in to comment.