Typography and Layout components
Closes #3695 (closed) #3616 (closed) #3696 (closed)
Following the scope on #3608 (closed)
The Typography Components
Implemented as H1
H2
H3
H4
B1
B2
B3
following design's Header1
Header2
Header3
Header4
Body1
Body2
Body3
.
The Layout Components
This was spined out during the replacement of the Header and Body Typography ones. As the legacy version use a lot of spacing style definitions on the text itself, for avoiding reworking on it later the idea was to understand if we have reach a point of the components definition where we could move towards creating them on a screen by screen basis.
I've reduced them to Row
, Column
, Spacer
, which should be enough to replace almost every pattern currently used for displaying the base. The Spacer
props are a reflection on the definition of spacing that comes from the UI design side with the XS
S
M
L
XL
...
approach.
I still have a couple doubts if the Spacer
should be built-in or left out of the common base components (Icon, Typography, Button, ..) as outside of the spacing realm (Column
, Row
, Spacer
) it is sparsely used. The conflicting points are:
- Although sparsely used it does add an extra view to the tree. Eventually this tree is necessary for the structure, but eventually it's redundant.
- If we choose to build it inside every component it can create an overhead call to the
getSpacingStylesNext
that loops through the component'sextra
props on component mount.
The current idea is to leave it as a wrapper and try to understand how common will be for it to be used on the common base components and how much would it affect each screen render profile.
@msantang78 On this regard, the Layout
components are a shortcut for spacing and organization. On components that are rendered multiple times and also on lists we should keep it plain, importing the spacing from the UI Tokens
itself.
About the spacing and the absence of padding props
There is no padding prop shortcut and although the Spacer does use margin internally, it should be interpreted as a way of adding separation between elements. Padding should be used internally to every component
/ feature
logic and accessed through flags or the type
prop which are defined at a Design level.
Drawer comparison example
I have replaced the Drawer
structure in an attempt to understand if it would already make sense for us to start using this approach of Screen/Screen replacement. It all went well, it reduces the logic involved for crafting it and the readability gets way cleaner and it's a nice step towards being able to use the MULTIPLIER
to resize the full app structure based on screen size.
const WITH_BASE = (
<Row left="XL2" right="XL" bottom="XXL">
<Avatar source={avatar} size="medium" onPress={onUserPress} />
<Column flex centerStart horizontal="M">
<H2 onPress={onUserPress} bold>
{name || `@${username}`}
</H2>
{name && (
<B1 flat light onPress={onUserPress} testID="channelUsername">
@{username}
</B1>
)}
</Column>
<IconButton
scale
color="SecondaryText"
name="account-multi"
testID="multiUserIcon"
onPress={onIconPress}
/>
</Row>
);
const LEGACY = (
<View style={styles.headerContainer}>
<TouchableOpacity onPress={navToChannel}>
<Image source={avatar} style={styles.wrappedAvatar} />
</TouchableOpacity>
<View style={styles.row}>
<View style={titleContainerStyle}>
<MText style={titleStyle} onPress={navToChannel}>
{channel.name || `@${channel.username}`}
</MText>
{channel.name && (
<MText
onPress={navToChannel}
style={subtitleStyle}
testID="channelUsername">
@{channel.username}
</MText>
)}
</View>
<IconButton
scale
color="SecondaryText"
name="account-multi"
testID="multiUserIcon"
onPress={() => props.navigation.navigate('MultiUserScreen')}
/>
</View>
</View>
);
const styles = StyleSheet.create({
titleText: {
fontFamily: 'Roboto',
fontSize: Platform.select({ ios: 26, android: 24 }),
fontWeight: '700',
},
subTitleText: {
fontFamily: 'Roboto',
fontSize: Platform.select({ ios: 16, android: 15 }),
fontWeight: '400',
},
headerContainer: {
flexDirection: 'row',
justifyContent: 'flex-start',
paddingTop: Platform.select({ ios: 33, android: 23 }),
paddingLeft: 40,
paddingBottom: 25,
borderBottomWidth: StyleSheet.hairlineWidth,
borderBottomColor: '#CCC',
},
wrappedAvatar: {
height: 55,
width: 55,
borderRadius: 55,
},
row: {
flexDirection: 'row',
flex: 1,
paddingRight: 30,
},
});
const subtitleStyle = ThemedStyles.combine(
styles.subTitleText,
'colorSecondaryText',
);
const titleContainerStyle = ThemedStyles.combine('flexColumn', 'marginLeft2x');
const titleStyle = ThemedStyles.combine(styles.titleText, 'colorPrimaryText');