Skip to content

Instantly share code, notes, and snippets.

@jennmueng
Created April 10, 2019 18:25
Show Gist options
  • Save jennmueng/7fca2f6df7a52fa1d91f25af97eded73 to your computer and use it in GitHub Desktop.
Save jennmueng/7fca2f6df7a52fa1d91f25af97eded73 to your computer and use it in GitHub Desktop.
// @flow
import React from 'react';
import { Animated } from 'react-native';
import styled from 'styled-components';
import type { DeviceProps } from '../../../flow/general';
import Stockholm from '../../assets/stockholm/stockholm';
import IconButton from '../feedback/iconButton';
import { PageTitle, SubHeader } from '../boilerplate/text';
const StaticHeader = ({
title,
subTitle,
back,
scrollOffset,
rightButtons,
reduceForehead,
deviceProps
}: {
title: string,
subTitle?: string,
back?: Function,
reduceForehead?: boolean,
rightButtons?: any,
scrollOffset?: Object, // eslint-disable-line
deviceProps: DeviceProps
}) => {
const maxHeaderHeight = deviceProps.maxHeaderHeight - (reduceForehead ? 10 : 0);
return !scrollOffset ? (
<HeaderContainer
style={{
height: maxHeaderHeight,
width: deviceProps.width
}}
deviceProps={deviceProps}
>
<TitleContainer deviceProps={deviceProps}>
<PageTitle
style={{
maxWidth: deviceProps.width - 40
}}
>
{title}
</PageTitle>
<SubHeader>{subTitle}</SubHeader>
</TitleContainer>
{back && (
<BackContainer deviceProps={deviceProps}>
<IconButton
action={back}
icon={
<Stockholm icon="back" color="#363B48" style={{ marginLeft: -2 }} height={34} width={34} />
}
backingColor="transparent"
/>
</BackContainer>
)}
</HeaderContainer>
) : (
<HeaderContainer
style={{
height: maxHeaderHeight,
transform: [
{
translateY: scrollOffset.interpolate({
inputRange: [-1, 0, maxHeaderHeight - deviceProps.minHeaderHeight],
outputRange: [1, 0, -(maxHeaderHeight - deviceProps.minHeaderHeight)],
extrapolateRight: 'clamp'
})
}
],
width: deviceProps.width
}}
deviceProps={deviceProps}
>
<Background
style={{
opacity: scrollOffset.interpolate({
inputRange: [0, maxHeaderHeight - deviceProps.minHeaderHeight],
outputRange: [0, 1],
extrapolate: 'clamp'
})
}}
/>
<AlternativeContainer
style={{
opacity: scrollOffset.interpolate({
inputRange: [
(maxHeaderHeight - deviceProps.minHeaderHeight) / 2,
maxHeaderHeight - deviceProps.minHeaderHeight
],
outputRange: [0, 1],
extrapolate: 'clamp'
})
}}
>
<AlternativeText>{title}</AlternativeText>
</AlternativeContainer>
<NameInputContainer deviceProps={deviceProps}>
<TextOpacityContainer
style={{
opacity: scrollOffset.interpolate({
inputRange: [0, (maxHeaderHeight - deviceProps.minHeaderHeight) / 2],
outputRange: [1, 0],
extrapolateRight: 'clamp'
})
}}
>
<PageTitle
style={{
maxWidth: deviceProps.width - 40
}}
>
{title}
</PageTitle>
<SubHeader>{subTitle}</SubHeader>
</TextOpacityContainer>
<ButtonContainer
style={{
transform: [
{
translateY: scrollOffset.interpolate({
inputRange: [0, maxHeaderHeight - deviceProps.minHeaderHeight],
outputRange: [0, deviceProps.buttonOffsetUpper - deviceProps.statusBarHeight + 5],
extrapolate: 'clamp'
})
}
]
}}
>
{rightButtons}
</ButtonContainer>
</NameInputContainer>
{back && (
<BackContainer
style={{
transform: [
{
translateY: scrollOffset.interpolate({
inputRange: [0, maxHeaderHeight - deviceProps.minHeaderHeight],
outputRange: [0, getButtonOffset(deviceProps)],
extrapolateRight: 'clamp'
})
}
]
}}
deviceProps={deviceProps}
>
<IconButton
action={back}
icon={
<Stockholm icon="back" color="#363B48" style={{ marginLeft: -2 }} height={34} width={34} />
}
backingColor="transparent"
/>
</BackContainer>
)}
</HeaderContainer>
);
};
StaticHeader.defaultProps = {
subTitle: ''
};
export default StaticHeader;
const getButtonOffset = (deviceProps: DeviceProps) => {
const { profile, buttonOffset } = deviceProps;
switch (profile) {
case 1:
return buttonOffset;
case 4:
return 50;
default:
return buttonOffset + 8;
}
};
const TitleContainer = styled.View`
position: absolute;
width: ${props => props.deviceProps.width - 40};
bottom: 5;
left: 20;
`;
const HeaderContainer = Animated.createAnimatedComponent(styled.View`
margin-left: -20px;
`);
const NameInputContainer = styled.View`
position: absolute;
width: ${props => props.deviceProps.width - 40};
bottom: 5;
left: 20;
`;
const TextOpacityContainer = Animated.createAnimatedComponent(styled.View``);
const Background = Animated.createAnimatedComponent(styled.View`
width: 100%;
height: 100%;
position: absolute;
background-color: #fff;
`);
const AlternativeText = styled.Text`
font-size: 20;
font-family: Lato-Black;
color: #363b48;
margin-bottom: 2px;
width: 100%;
text-align: center;
`;
const AlternativeContainer = Animated.createAnimatedComponent(styled.View`
bottom: 13;
position: absolute;
width: 100%;
`);
const BackContainer = Animated.createAnimatedComponent(styled.View`
position: absolute;
left: 20;
flex-direction: row;
align-items: center;
justify-content: flex-start;
height: 24;
top: ${({ deviceProps: { buttonOffset, profile } }) =>
(profile !== 1 && profile !== 4 ? buttonOffset - 8 : buttonOffset)};
`);
const ButtonContainer = Animated.createAnimatedComponent(styled.View`
position: absolute;
right: 0;
top: 0;
`);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment