Skip to content

Typography and Layout components

Rafael Caferati requested to merge feat/typography-implementation into release/4.20.0

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's extra 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');
Edited by Rafael Caferati

Merge request reports