Rework all typography

zio/stable
Paul Frazee 2023-01-18 11:15:40 -06:00
parent df4acbd683
commit 77580ab6a4
28 changed files with 355 additions and 162 deletions

View File

@ -50,9 +50,9 @@ export function Autocomplete({
key={i} key={i}
style={[pal.border, styles.item]} style={[pal.border, styles.item]}
onPress={() => onSelect(item.handle)}> onPress={() => onSelect(item.handle)}>
<Text style={pal.text}> <Text type="md-medium" style={pal.text}>
{item.displayName || item.handle} {item.displayName || item.handle}
<Text type="body2" style={pal.textLight}> <Text type="sm" style={pal.textLight}>
&nbsp;@{item.handle} &nbsp;@{item.handle}
</Text> </Text>
</Text> </Text>

View File

@ -243,12 +243,12 @@ export const ComposePost = observer(function ComposePost({
/> />
<View style={styles.replyToPost}> <View style={styles.replyToPost}>
<TextLink <TextLink
type="h5" type="xl-medium"
href={`/profile/${replyTo.author.handle}`} href={`/profile/${replyTo.author.handle}`}
text={replyTo.author.displayName || replyTo.author.handle} text={replyTo.author.displayName || replyTo.author.handle}
style={[pal.text]} style={[pal.text]}
/> />
<Text style={pal.text} numberOfLines={6}> <Text type="post-text" style={pal.text} numberOfLines={6}>
{replyTo.text} {replyTo.text}
</Text> </Text>
</View> </View>
@ -408,9 +408,12 @@ const styles = StyleSheet.create({
textInput: { textInput: {
flex: 1, flex: 1,
padding: 5, padding: 5,
fontSize: 18,
marginLeft: 8, marginLeft: 8,
alignSelf: 'flex-start', alignSelf: 'flex-start',
fontSize: 18,
letterSpacing: 0.2,
fontWeight: '400',
lineHeight: 23.4, // 1.3*16
}, },
replyToLayout: { replyToLayout: {
flexDirection: 'row', flexDirection: 'row',

View File

@ -26,7 +26,7 @@ export function ComposePrompt({
]} ]}
onPress={onPressCompose}> onPress={onPressCompose}>
<View style={styles.textContainer}> <View style={styles.textContainer}>
<Text type="h5" style={[pal.textLight, {fontWeight: 'normal'}]}> <Text type="lg" style={[pal.textLight]}>
{text} {text}
</Text> </Text>
</View> </View>

View File

@ -160,7 +160,7 @@ const User = ({
/> />
</View> </View>
<View style={styles.actorContent}> <View style={styles.actorContent}>
<Text type="h5" style={pal.text} numberOfLines={1}> <Text type="title-sm" style={pal.text} numberOfLines={1}>
{item.displayName || item.handle} {item.displayName || item.handle}
</Text> </Text>
<Text style={pal.textLight} numberOfLines={1}> <Text style={pal.textLight} numberOfLines={1}>

View File

@ -130,17 +130,19 @@ export const PostThreadItem = observer(function PostThreadItem({
</View> </View>
<View style={styles.layoutContent}> <View style={styles.layoutContent}>
<View style={[styles.meta, {paddingTop: 5, paddingBottom: 0}]}> <View style={[styles.meta, {paddingTop: 5, paddingBottom: 0}]}>
<View style={{flexDirection: 'row', alignItems: 'baseline'}}>
<Link <Link
style={styles.metaItem} style={styles.metaItem}
href={authorHref} href={authorHref}
title={authorTitle}> title={authorTitle}>
<Text type="h5" style={[pal.text]} numberOfLines={1}> <Text type="xl-bold" style={[pal.text]} numberOfLines={1}>
{item.post.author.displayName || item.post.author.handle} {item.post.author.displayName || item.post.author.handle}
</Text> </Text>
</Link> </Link>
<Text type="h6" style={[styles.metaItem, pal.textLight]}> <Text type="md" style={[styles.metaItem, pal.textLight]}>
&middot; {ago(item.post.indexedAt)} &middot; {ago(item.post.indexedAt)}
</Text> </Text>
</View>
<View style={s.flex1} /> <View style={s.flex1} />
<PostDropdownBtn <PostDropdownBtn
style={styles.metaItem} style={styles.metaItem}
@ -161,7 +163,7 @@ export const PostThreadItem = observer(function PostThreadItem({
style={styles.metaItem} style={styles.metaItem}
href={authorHref} href={authorHref}
title={authorTitle}> title={authorTitle}>
<Text type="h6" style={[pal.textLight]} numberOfLines={1}> <Text type="md" style={[pal.textLight]} numberOfLines={1}>
@{item.post.author.handle} @{item.post.author.handle}
</Text> </Text>
</Link> </Link>
@ -176,9 +178,10 @@ export const PostThreadItem = observer(function PostThreadItem({
styles.postTextLargeContainer, styles.postTextLargeContainer,
]}> ]}>
<RichText <RichText
type="h3" type="post-text-lg"
text={record.text} text={record.text}
entities={record.entities} entities={record.entities}
lineHeight={1.3}
/> />
</View> </View>
) : undefined} ) : undefined}
@ -190,8 +193,8 @@ export const PostThreadItem = observer(function PostThreadItem({
style={styles.expandedInfoItem} style={styles.expandedInfoItem}
href={repostsHref} href={repostsHref}
title={repostsTitle}> title={repostsTitle}>
<Text type="h6" style={pal.textLight}> <Text type="lg" style={pal.textLight}>
<Text type="h5" style={pal.text}> <Text type="xl-bold" style={pal.text}>
{item.post.repostCount} {item.post.repostCount}
</Text>{' '} </Text>{' '}
{pluralize(item.post.repostCount, 'repost')} {pluralize(item.post.repostCount, 'repost')}
@ -205,8 +208,8 @@ export const PostThreadItem = observer(function PostThreadItem({
style={styles.expandedInfoItem} style={styles.expandedInfoItem}
href={upvotesHref} href={upvotesHref}
title={upvotesTitle}> title={upvotesTitle}>
<Text type="h6" style={pal.textLight}> <Text type="lg" style={pal.textLight}>
<Text type="h5" style={pal.text}> <Text type="xl-bold" style={pal.text}>
{item.post.upvoteCount} {item.post.upvoteCount}
</Text>{' '} </Text>{' '}
{pluralize(item.post.upvoteCount, 'like')} {pluralize(item.post.upvoteCount, 'like')}
@ -289,14 +292,16 @@ export const PostThreadItem = observer(function PostThreadItem({
{item.post.author.viewer?.muted ? ( {item.post.author.viewer?.muted ? (
<View style={[styles.mutedWarning, pal.btn]}> <View style={[styles.mutedWarning, pal.btn]}>
<FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} /> <FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} />
<Text type="body2">This post is by a muted account.</Text> <Text type="sm">This post is by a muted account.</Text>
</View> </View>
) : record.text ? ( ) : record.text ? (
<View style={styles.postTextContainer}> <View style={styles.postTextContainer}>
<RichText <RichText
type="post-text"
text={record.text} text={record.text}
entities={record.entities} entities={record.entities}
style={pal.text} style={pal.text}
lineHeight={1.3}
/> />
</View> </View>
) : ( ) : (
@ -394,6 +399,7 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
flexWrap: 'wrap', flexWrap: 'wrap',
paddingBottom: 8, paddingBottom: 8,
paddingRight: 20,
minHeight: 36, minHeight: 36,
}, },
postTextLargeContainer: { postTextLargeContainer: {

View File

@ -20,7 +20,6 @@ import {Text} from '../util/text/Text'
import {RichText} from '../util/text/RichText' import {RichText} from '../util/text/RichText'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
import {UserAvatar} from '../util/UserAvatar' import {UserAvatar} from '../util/UserAvatar'
import {ErrorMessage} from '../util/error/ErrorMessage'
import {useStores} from '../../../state' import {useStores} from '../../../state'
import {s, colors} from '../../lib/styles' import {s, colors} from '../../lib/styles'
import {usePalette} from '../../lib/hooks/usePalette' import {usePalette} from '../../lib/hooks/usePalette'
@ -166,12 +165,12 @@ export const Post = observer(function Post({
size={9} size={9}
style={[pal.textLight, s.mr5]} style={[pal.textLight, s.mr5]}
/> />
<Text type="body2" style={[pal.textLight, s.mr2]}> <Text type="sm" style={[pal.textLight, s.mr2]}>
Reply to Reply to
</Text> </Text>
<Link href={replyHref} title="Parent post"> <Link href={replyHref} title="Parent post">
<UserInfoText <UserInfoText
type="body2" type="sm"
did={replyAuthorDid} did={replyAuthorDid}
attr="displayName" attr="displayName"
style={[pal.textLight]} style={[pal.textLight]}
@ -182,11 +181,16 @@ export const Post = observer(function Post({
{item.post.author.viewer?.muted ? ( {item.post.author.viewer?.muted ? (
<View style={[styles.mutedWarning, pal.btn]}> <View style={[styles.mutedWarning, pal.btn]}>
<FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} /> <FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} />
<Text type="body2">This post is by a muted account.</Text> <Text type="sm">This post is by a muted account.</Text>
</View> </View>
) : record.text ? ( ) : record.text ? (
<View style={styles.postTextContainer}> <View style={styles.postTextContainer}>
<RichText text={record.text} entities={record.entities} /> <RichText
type="post-text"
text={record.text}
entities={record.entities}
lineHeight={1.3}
/>
</View> </View>
) : ( ) : (
<View style={{height: 5}} /> <View style={{height: 5}} />

View File

@ -15,7 +15,7 @@ import {PostEmbeds} from '../util/PostEmbeds'
import {RichText} from '../util/text/RichText' import {RichText} from '../util/text/RichText'
import * as Toast from '../util/Toast' import * as Toast from '../util/Toast'
import {UserAvatar} from '../util/UserAvatar' import {UserAvatar} from '../util/UserAvatar'
import {s, colors} from '../../lib/styles' import {s} from '../../lib/styles'
import {useStores} from '../../../state' import {useStores} from '../../../state'
import {useTheme} from '../../lib/ThemeContext' import {useTheme} from '../../lib/ThemeContext'
import {usePalette} from '../../lib/hooks/usePalette' import {usePalette} from '../../lib/hooks/usePalette'
@ -30,7 +30,6 @@ export const FeedItem = observer(function ({
ignoreMuteFor?: string ignoreMuteFor?: string
}) { }) {
const store = useStores() const store = useStores()
const theme = useTheme()
const pal = usePalette('default') const pal = usePalette('default')
const [deleted, setDeleted] = useState(false) const [deleted, setDeleted] = useState(false)
const record = item.postRecord const record = item.postRecord
@ -144,12 +143,7 @@ export const FeedItem = observer(function ({
icon="retweet" icon="retweet"
style={[styles.includeReasonIcon, {color: pal.colors.textLight}]} style={[styles.includeReasonIcon, {color: pal.colors.textLight}]}
/> />
<Text <Text type="sm-bold" style={pal.textLight}>
type="body2"
style={{
fontWeight: '600',
color: pal.colors.textLight,
}}>
Reposted by{' '} Reposted by{' '}
{item.reasonRepost.by.displayName || item.reasonRepost.by.handle} {item.reasonRepost.by.displayName || item.reasonRepost.by.handle}
</Text> </Text>
@ -180,15 +174,15 @@ export const FeedItem = observer(function ({
size={9} size={9}
style={[{color: pal.colors.textLight}, s.mr5]} style={[{color: pal.colors.textLight}, s.mr5]}
/> />
<Text type="body2" style={[pal.textLight, s.mr2]}> <Text type="md" style={[pal.textLight, s.mr2]}>
Reply to Reply to
</Text> </Text>
<Link href={replyHref} title="Parent post"> <Link href={replyHref} title="Parent post">
<UserInfoText <UserInfoText
type="body2" type="md"
did={replyAuthorDid} did={replyAuthorDid}
attr="displayName" attr="displayName"
style={[pal.textLight]} style={[pal.textLight, s.ml2]}
/> />
</Link> </Link>
</View> </View>
@ -197,14 +191,15 @@ export const FeedItem = observer(function ({
ignoreMuteFor !== item.post.author.did ? ( ignoreMuteFor !== item.post.author.did ? (
<View style={[styles.mutedWarning, pal.btn]}> <View style={[styles.mutedWarning, pal.btn]}>
<FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} /> <FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} />
<Text type="body2">This post is by a muted account.</Text> <Text type="sm">This post is by a muted account.</Text>
</View> </View>
) : record.text ? ( ) : record.text ? (
<View style={styles.postTextContainer}> <View style={styles.postTextContainer}>
<RichText <RichText
type="body1" type="post-text"
text={record.text} text={record.text}
entities={record.entities} entities={record.entities}
lineHeight={1.3}
/> />
</View> </View>
) : ( ) : (
@ -251,7 +246,7 @@ export const FeedItem = observer(function ({
<Circle x="2" y="22" r="1.5" fill={pal.colors.replyLineDot} /> <Circle x="2" y="22" r="1.5" fill={pal.colors.replyLineDot} />
</Svg> </Svg>
</View> </View>
<Text style={[pal.link, theme.typography.body2]}> <Text type="md" style={pal.link}>
View full thread View full thread
</Text> </Text>
</Link> </Link>
@ -322,6 +317,7 @@ const styles = StyleSheet.create({
alignItems: 'center', alignItems: 'center',
flexWrap: 'wrap', flexWrap: 'wrap',
paddingBottom: 4, paddingBottom: 4,
paddingRight: 20,
}, },
embed: { embed: {
marginBottom: 6, marginBottom: 6,

View File

@ -39,7 +39,7 @@ export function ProfileCard({
<Text style={[s.bold, pal.text]} numberOfLines={1}> <Text style={[s.bold, pal.text]} numberOfLines={1}>
{displayName || handle} {displayName || handle}
</Text> </Text>
<Text type="body2" style={[pal.textLight]} numberOfLines={1}> <Text type="sm" style={[pal.textLight]} numberOfLines={1}>
@{handle} @{handle}
</Text> </Text>
</View> </View>

View File

@ -99,7 +99,7 @@ const User = ({item}: {item: FollowerItem}) => {
<Text style={[s.bold, pal.text]}> <Text style={[s.bold, pal.text]}>
{item.displayName || item.handle} {item.displayName || item.handle}
</Text> </Text>
<Text type="body2" style={[pal.textLight]}> <Text type="sm" style={[pal.textLight]}>
@{item.handle} @{item.handle}
</Text> </Text>
</View> </View>

View File

@ -99,7 +99,7 @@ const User = ({item}: {item: FollowItem}) => {
<Text style={[s.bold, pal.text]}> <Text style={[s.bold, pal.text]}>
{item.displayName || item.handle} {item.displayName || item.handle}
</Text> </Text>
<Text type="body2" style={pal.textLight}> <Text type="sm" style={pal.textLight}>
@{item.handle} @{item.handle}
</Text> </Text>
</View> </View>

View File

@ -108,7 +108,7 @@ export const ProfileHeader = observer(function ProfileHeader({
/> />
</View> </View>
<View style={styles.displayNameLine}> <View style={styles.displayNameLine}>
<Text type="h2" style={[pal.text, {lineHeight: 38}]}> <Text type="title-xl" style={[pal.text, {lineHeight: 38}]}>
{view.displayName || view.handle} {view.displayName || view.handle}
</Text> </Text>
</View> </View>
@ -200,7 +200,7 @@ export const ProfileHeader = observer(function ProfileHeader({
) : undefined} ) : undefined}
</View> </View>
<View style={styles.displayNameLine}> <View style={styles.displayNameLine}>
<Text type="h2" style={[pal.text, {lineHeight: 38}]}> <Text type="title-xl" style={[pal.text, {lineHeight: 38}]}>
{view.displayName || view.handle} {view.displayName || view.handle}
</Text> </Text>
</View> </View>
@ -212,10 +212,10 @@ export const ProfileHeader = observer(function ProfileHeader({
testID="profileHeaderFollowersButton" testID="profileHeaderFollowersButton"
style={[s.flexRow, s.mr10]} style={[s.flexRow, s.mr10]}
onPress={onPressFollowers}> onPress={onPressFollowers}>
<Text type="body2" style={[s.bold, s.mr2, pal.text]}> <Text type="md" style={[s.bold, s.mr2, pal.text]}>
{view.followersCount} {view.followersCount}
</Text> </Text>
<Text type="body2" style={[pal.textLight]}> <Text type="md" style={[pal.textLight]}>
{pluralize(view.followersCount, 'follower')} {pluralize(view.followersCount, 'follower')}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
@ -224,19 +224,19 @@ export const ProfileHeader = observer(function ProfileHeader({
testID="profileHeaderFollowsButton" testID="profileHeaderFollowsButton"
style={[s.flexRow, s.mr10]} style={[s.flexRow, s.mr10]}
onPress={onPressFollows}> onPress={onPressFollows}>
<Text type="body2" style={[s.bold, s.mr2, pal.text]}> <Text type="md" style={[s.bold, s.mr2, pal.text]}>
{view.followsCount} {view.followsCount}
</Text> </Text>
<Text type="body2" style={[pal.textLight]}> <Text type="md" style={[pal.textLight]}>
following following
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
) : undefined} ) : undefined}
<View style={[s.flexRow, s.mr10]}> <View style={[s.flexRow, s.mr10]}>
<Text type="body2" style={[s.bold, s.mr2, pal.text]}> <Text type="md" style={[s.bold, s.mr2, pal.text]}>
{view.postsCount} {view.postsCount}
</Text> </Text>
<Text type="body2" style={[pal.textLight]}> <Text type="md" style={[pal.textLight]}>
{pluralize(view.postsCount, 'post')} {pluralize(view.postsCount, 'post')}
</Text> </Text>
</View> </View>
@ -255,7 +255,7 @@ export const ProfileHeader = observer(function ProfileHeader({
icon={['far', 'eye-slash']} icon={['far', 'eye-slash']}
style={[pal.text, s.mr5]} style={[pal.text, s.mr5]}
/> />
<Text type="body2" style={[s.mr2, pal.text]}> <Text type="md" style={[s.mr2, pal.text]}>
Account muted. Account muted.
</Text> </Text>
</View> </View>

View File

@ -29,7 +29,7 @@ export function EmptyState({
/> />
)} )}
</View> </View>
<Text type="body1" style={[pal.textLight, styles.text]}> <Text type="xl" style={[pal.textLight, styles.text]}>
{message} {message}
</Text> </Text>
</View> </View>

View File

@ -58,7 +58,7 @@ export const Link = observer(function Link({
}) })
export const TextLink = observer(function Link({ export const TextLink = observer(function Link({
type = 'body1', type = 'md',
style, style,
href, href,
text, text,

View File

@ -92,21 +92,18 @@ export function PostEmbeds({
/> />
)} )}
<View style={styles.extInner}> <View style={styles.extInner}>
<Text <Text type="sm-bold" numberOfLines={2} style={[pal.text]}>
type="body2"
numberOfLines={2}
style={[pal.text, styles.extTitle]}>
{link.title || link.uri} {link.title || link.uri}
</Text> </Text>
<Text <Text
type="body2" type="sm"
numberOfLines={1} numberOfLines={1}
style={[pal.textLight, styles.extUri]}> style={[pal.textLight, styles.extUri]}>
{link.uri} {link.uri}
</Text> </Text>
{link.description ? ( {link.description ? (
<Text <Text
type="body2" type="sm"
numberOfLines={2} numberOfLines={2}
style={[pal.text, styles.extDescription]}> style={[pal.text, styles.extDescription]}>
{link.description} {link.description}
@ -140,9 +137,6 @@ const styles = StyleSheet.create({
extImageFallback: { extImageFallback: {
height: 160, height: 160,
}, },
extTitle: {
fontWeight: '600',
},
extUri: { extUri: {
marginTop: 2, marginTop: 2,
}, },

View File

@ -40,16 +40,16 @@ export function PostMeta(opts: PostMetaOpts) {
style={[styles.metaItem, styles.maxWidth]} style={[styles.metaItem, styles.maxWidth]}
href={opts.authorHref} href={opts.authorHref}
title={opts.authorHandle}> title={opts.authorHandle}>
<Text type="h5" style={[pal.text]} numberOfLines={1}> <Text type="lg-bold" style={[pal.text]} numberOfLines={1}>
{displayName} {displayName}
{handle ? ( {handle ? (
<Text type="h6" style={[pal.textLight]}> <Text type="md" style={[pal.textLight]}>
&nbsp;{handle} &nbsp;{handle}
</Text> </Text>
) : undefined} ) : undefined}
</Text> </Text>
</Link> </Link>
<Text type="h6" style={[styles.metaItem, pal.textLight]}> <Text type="md" style={[styles.metaItem, pal.textLight]}>
&middot; {ago(opts.timestamp)} &middot; {ago(opts.timestamp)}
</Text> </Text>
</View> </View>

View File

@ -8,7 +8,7 @@ import {useStores} from '../../../state'
import {TypographyVariant} from '../../lib/ThemeContext' import {TypographyVariant} from '../../lib/ThemeContext'
export function UserInfoText({ export function UserInfoText({
type = 'body1', type = 'md',
did, did,
attr, attr,
loading, loading,

View File

@ -68,12 +68,12 @@ export const ViewHeader = observer(function ViewHeader({
)} )}
</TouchableOpacity> </TouchableOpacity>
<View style={styles.titleContainer} pointerEvents="none"> <View style={styles.titleContainer} pointerEvents="none">
<Text type="h4" style={[pal.text, styles.title]}> <Text type="title" style={[pal.text, styles.title]}>
{title} {title}
</Text> </Text>
{subtitle ? ( {subtitle ? (
<Text <Text
type="h5" type="title-sm"
style={[styles.subtitle, pal.textLight]} style={[styles.subtitle, pal.textLight]}
numberOfLines={1}> numberOfLines={1}>
{subtitle} {subtitle}

View File

@ -31,7 +31,7 @@ export function ErrorMessage({
<FontAwesomeIcon icon="exclamation" style={pal.text} size={16} /> <FontAwesomeIcon icon="exclamation" style={pal.text} size={16} />
</View> </View>
<Text <Text
type="body2" type="sm"
style={[styles.message, pal.text]} style={[styles.message, pal.text]}
numberOfLines={numberOfLines}> numberOfLines={numberOfLines}>
{message} {message}

View File

@ -36,14 +36,14 @@ export function ErrorScreen({
/> />
</View> </View>
</View> </View>
<Text type="h3" style={[styles.title, pal.text]}> <Text type="title-lg" style={[styles.title, pal.text]}>
{title} {title}
</Text> </Text>
<Text style={[styles.message, pal.textLight]}>{message}</Text> <Text style={[styles.message, pal.textLight]}>{message}</Text>
{details && ( {details && (
<Text <Text
testID={`${testID}-details`} testID={`${testID}-details`}
type="body2" type="sm"
style={[ style={[
styles.details, styles.details,
pal.textInverted, pal.textInverted,

View File

@ -15,21 +15,23 @@ type Entity = {
} }
export function RichText({ export function RichText({
type = 'body1', type = 'md',
text, text,
entities, entities,
lineHeight = 1.2,
style, style,
numberOfLines, numberOfLines,
}: { }: {
type?: TypographyVariant type?: TypographyVariant
text: string text: string
entities?: Entity[] entities?: Entity[]
lineHeight?: number
style?: StyleProp<TextStyle> style?: StyleProp<TextStyle>
numberOfLines?: number numberOfLines?: number
}) { }) {
const theme = useTheme() const theme = useTheme()
const pal = usePalette('default') const pal = usePalette('default')
const lineHeightStyle = lh(theme, type, 1.2) const lineHeightStyle = lh(theme, type, lineHeight)
if (!entities?.length) { if (!entities?.length) {
if (/^\p{Extended_Pictographic}+$/u.test(text) && text.length <= 5) { if (/^\p{Extended_Pictographic}+$/u.test(text) && text.length <= 5) {
style = { style = {

View File

@ -8,7 +8,7 @@ export type CustomTextProps = TextProps & {
} }
export function Text({ export function Text({
type = 'body1', type = 'md',
children, children,
style, style,
...props ...props

View File

@ -27,21 +27,39 @@ export type ShapeName = 'button' | 'bigButton' | 'smallButton'
export type Shapes = Record<ShapeName, ViewStyle> export type Shapes = Record<ShapeName, ViewStyle>
export type TypographyVariant = export type TypographyVariant =
| 'h1' | 'xl-thin'
| 'h2' | 'xl'
| 'h3' | 'xl-medium'
| 'h4' | 'xl-bold'
| 'h5' | 'xl-heavy'
| 'h6' | 'lg-thin'
| 'subtitle1' | 'lg'
| 'subtitle2' | 'lg-medium'
| 'body1' | 'lg-bold'
| 'body2' | 'lg-heavy'
| 'md-thin'
| 'md'
| 'md-medium'
| 'md-bold'
| 'md-heavy'
| 'sm-thin'
| 'sm'
| 'sm-medium'
| 'sm-bold'
| 'sm-heavy'
| 'xs-thin'
| 'xs'
| 'xs-medium'
| 'xs-bold'
| 'xs-heavy'
| 'title-xl'
| 'title-lg'
| 'title'
| 'title-sm'
| 'post-text-lg'
| 'post-text'
| 'button' | 'button'
| 'caption' | 'mono'
| 'overline1'
| 'overline2'
| 'mono1'
export type Typography = Record<TypographyVariant, TextStyle> export type Typography = Record<TypographyVariant, TextStyle>
export interface Theme { export interface Theme {

View File

@ -75,70 +75,167 @@ export const defaultTheme: Theme = {
}, },
}, },
typography: { typography: {
h1: { 'xl-thin': {
fontSize: 48, fontSize: 17,
letterSpacing: 0.25,
fontWeight: '300',
},
xl: {
fontSize: 17,
letterSpacing: 0.25,
fontWeight: '400',
},
'xl-medium': {
fontSize: 17,
letterSpacing: 0.25,
fontWeight: '500', fontWeight: '500',
}, },
h2: { 'xl-bold': {
fontSize: 17,
letterSpacing: 0.25,
fontWeight: '700',
},
'xl-heavy': {
fontSize: 17,
letterSpacing: 0.25,
fontWeight: '800',
},
'lg-thin': {
fontSize: 16,
letterSpacing: 0.25,
fontWeight: '300',
},
lg: {
fontSize: 16,
letterSpacing: 0.25,
fontWeight: '400',
},
'lg-medium': {
fontSize: 16,
letterSpacing: 0.25,
fontWeight: '500',
},
'lg-bold': {
fontSize: 16,
letterSpacing: 0.25,
fontWeight: '700',
},
'lg-heavy': {
fontSize: 16,
letterSpacing: 0.25,
fontWeight: '800',
},
'md-thin': {
fontSize: 15,
letterSpacing: 0.25,
fontWeight: '300',
},
md: {
fontSize: 15,
letterSpacing: 0.25,
fontWeight: '400',
},
'md-medium': {
fontSize: 15,
letterSpacing: 0.25,
fontWeight: '500',
},
'md-bold': {
fontSize: 15,
letterSpacing: 0.25,
fontWeight: '700',
},
'md-heavy': {
fontSize: 15,
letterSpacing: 0.25,
fontWeight: '800',
},
'sm-thin': {
fontSize: 14,
letterSpacing: 0.25,
fontWeight: '300',
},
sm: {
fontSize: 14,
letterSpacing: 0.25,
fontWeight: '400',
},
'sm-medium': {
fontSize: 14,
letterSpacing: 0.25,
fontWeight: '500',
},
'sm-bold': {
fontSize: 14,
letterSpacing: 0.25,
fontWeight: '700',
},
'sm-heavy': {
fontSize: 14,
letterSpacing: 0.25,
fontWeight: '800',
},
'xs-thin': {
fontSize: 13,
letterSpacing: 0.25,
fontWeight: '300',
},
xs: {
fontSize: 13,
letterSpacing: 0.25,
fontWeight: '400',
},
'xs-medium': {
fontSize: 13,
letterSpacing: 0.25,
fontWeight: '500',
},
'xs-bold': {
fontSize: 13,
letterSpacing: 0.25,
fontWeight: '700',
},
'xs-heavy': {
fontSize: 13,
letterSpacing: 0.25,
fontWeight: '800',
},
'title-xl': {
fontSize: 34, fontSize: 34,
letterSpacing: 0.25, letterSpacing: 0.25,
fontWeight: '500', fontWeight: '500',
}, },
h3: { 'title-lg': {
fontSize: 24, fontSize: 24,
fontWeight: '500', fontWeight: '500',
}, },
h4: { title: {
fontWeight: '500', fontWeight: '500',
fontSize: 20, fontSize: 20,
letterSpacing: 0.15, letterSpacing: 0.15,
}, },
h5: { 'title-sm': {
fontWeight: 'bold', fontWeight: 'bold',
fontSize: 17, fontSize: 17,
letterSpacing: 0.15, letterSpacing: 0.15,
}, },
h6: { 'post-text': {
fontWeight: '400',
fontSize: 15,
letterSpacing: 0.15,
},
subtitle1: {
fontSize: 16, fontSize: 16,
letterSpacing: 0.15,
},
subtitle2: {
fontWeight: '500',
fontSize: 14,
letterSpacing: 0.1,
},
body1: {
fontSize: 17,
letterSpacing: 0.2, letterSpacing: 0.2,
fontWeight: '400',
}, },
body2: { 'post-text-lg': {
fontSize: 14, fontSize: 24,
letterSpacing: 0.25, letterSpacing: 0.4,
fontWeight: '400',
}, },
button: { button: {
fontWeight: '500', fontWeight: '500',
fontSize: 14, fontSize: 14,
letterSpacing: 0.5, letterSpacing: 0.5,
}, },
caption: { mono: {
fontSize: 12,
letterSpacing: 0.4,
},
overline1: {
fontSize: 10,
letterSpacing: 1.5,
textTransform: 'uppercase',
},
overline2: {
fontSize: 14,
fontWeight: '600',
},
mono1: {
fontSize: 14, fontSize: 14,
fontFamily: Platform.OS === 'android' ? 'monospace' : 'Courier New', fontFamily: Platform.OS === 'android' ? 'monospace' : 'Courier New',
}, },

View File

@ -87,7 +87,7 @@ function Heading({label}: {label: string}) {
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<View style={{paddingTop: 10, paddingBottom: 5}}> <View style={{paddingTop: 10, paddingBottom: 5}}>
<Text type="h3" style={pal.text}> <Text type="title-lg" style={pal.text}>
{label} {label}
</Text> </Text>
</View> </View>
@ -97,14 +97,14 @@ function Heading({label}: {label: string}) {
function BaseView() { function BaseView() {
return ( return (
<View style={{paddingHorizontal: 10}}> <View style={{paddingHorizontal: 10}}>
<Heading label="Typography" />
<TypographyView />
<Heading label="Palettes" /> <Heading label="Palettes" />
<PaletteView palette="default" /> <PaletteView palette="default" />
<PaletteView palette="primary" /> <PaletteView palette="primary" />
<PaletteView palette="secondary" /> <PaletteView palette="secondary" />
<PaletteView palette="inverted" /> <PaletteView palette="inverted" />
<PaletteView palette="error" /> <PaletteView palette="error" />
<Heading label="Typography" />
<TypographyView />
<Heading label="Empty state" /> <Heading label="Empty state" />
<EmptyStateView /> <EmptyStateView />
<Heading label="Loading placeholders" /> <Heading label="Loading placeholders" />
@ -197,36 +197,109 @@ function TypographyView() {
const pal = usePalette('default') const pal = usePalette('default')
return ( return (
<View style={[pal.view]}> <View style={[pal.view]}>
<Text type="h1" style={[pal.text]}> <Text type="xxl-thin" style={[pal.text]}>
Heading 1 'xxl-thin' lorem ipsum dolor
</Text> </Text>
<Text type="h2" style={[pal.text]}> <Text type="xxl" style={[pal.text]}>
Heading 2 'xxl' lorem ipsum dolor
</Text> </Text>
<Text type="h3" style={[pal.text]}> <Text type="xxl-medium" style={[pal.text]}>
Heading 3 'xxl-medium' lorem ipsum dolor
</Text> </Text>
<Text type="h4" style={[pal.text]}> <Text type="xxl-bold" style={[pal.text]}>
Heading 4 'xxl-bold' lorem ipsum dolor
</Text> </Text>
<Text type="subtitle1" style={[pal.text]}> <Text type="xxl-heavy" style={[pal.text]}>
Subtitle 1 'xxl-heavy' lorem ipsum dolor
</Text> </Text>
<Text type="subtitle2" style={[pal.text]}> <Text type="xl-thin" style={[pal.text]}>
Subtitle 2 'xl-thin' lorem ipsum dolor
</Text> </Text>
<Text type="body1" style={[pal.text]}> <Text type="xl" style={[pal.text]}>
Body 1 'xl' lorem ipsum dolor
</Text> </Text>
<Text type="body2" style={[pal.text]}> <Text type="xl-medium" style={[pal.text]}>
Body 2 'xl-medium' lorem ipsum dolor
</Text>
<Text type="xl-bold" style={[pal.text]}>
'xl-bold' lorem ipsum dolor
</Text>
<Text type="xl-heavy" style={[pal.text]}>
'xl-heavy' lorem ipsum dolor
</Text>
<Text type="lg-thin" style={[pal.text]}>
'lg-thin' lorem ipsum dolor
</Text>
<Text type="lg" style={[pal.text]}>
'lg' lorem ipsum dolor
</Text>
<Text type="lg-medium" style={[pal.text]}>
'lg-medium' lorem ipsum dolor
</Text>
<Text type="lg-bold" style={[pal.text]}>
'lg-bold' lorem ipsum dolor
</Text>
<Text type="lg-heavy" style={[pal.text]}>
'lg-heavy' lorem ipsum dolor
</Text>
<Text type="md-thin" style={[pal.text]}>
'md-thin' lorem ipsum dolor
</Text>
<Text type="md" style={[pal.text]}>
'md' lorem ipsum dolor
</Text>
<Text type="md-medium" style={[pal.text]}>
'md-medium' lorem ipsum dolor
</Text>
<Text type="md-bold" style={[pal.text]}>
'md-bold' lorem ipsum dolor
</Text>
<Text type="md-heavy" style={[pal.text]}>
'md-heavy' lorem ipsum dolor
</Text>
<Text type="sm-thin" style={[pal.text]}>
'sm-thin' lorem ipsum dolor
</Text>
<Text type="sm" style={[pal.text]}>
'sm' lorem ipsum dolor
</Text>
<Text type="sm-medium" style={[pal.text]}>
'sm-medium' lorem ipsum dolor
</Text>
<Text type="sm-bold" style={[pal.text]}>
'sm-bold' lorem ipsum dolor
</Text>
<Text type="sm-heavy" style={[pal.text]}>
'sm-heavy' lorem ipsum dolor
</Text>
<Text type="xs-thin" style={[pal.text]}>
'xs-thin' lorem ipsum dolor
</Text>
<Text type="xs" style={[pal.text]}>
'xs' lorem ipsum dolor
</Text>
<Text type="xs-medium" style={[pal.text]}>
'xs-medium' lorem ipsum dolor
</Text>
<Text type="xs-bold" style={[pal.text]}>
'xs-bold' lorem ipsum dolor
</Text>
<Text type="xs-heavy" style={[pal.text]}>
'xs-heavy' lorem ipsum dolor
</Text>
<Text type="title-xl" style={[pal.text]}>
'title-xl' lorem ipsum dolor
</Text>
<Text type="title-lg" style={[pal.text]}>
'title-lg' lorem ipsum dolor
</Text>
<Text type="title" style={[pal.text]}>
'title' lorem ipsum dolor
</Text> </Text>
<Text type="button" style={[pal.text]}> <Text type="button" style={[pal.text]}>
Button Button
</Text> </Text>
<Text type="caption" style={[pal.text]}>
Caption
</Text>
<Text type="overline" style={[pal.text]}> <Text type="overline" style={[pal.text]}>
Overline Overline
</Text> </Text>

View File

@ -49,7 +49,7 @@ export const Log = observer(function Log({navIdx, visible}: ScreenParams) {
) : ( ) : (
<FontAwesomeIcon icon="exclamation" style={s.red3} /> <FontAwesomeIcon icon="exclamation" style={s.red3} />
)} )}
<Text type="body2" style={[styles.summary, pal.text]}> <Text type="sm" style={[styles.summary, pal.text]}>
{entry.summary} {entry.summary}
</Text> </Text>
{!!entry.details ? ( {!!entry.details ? (
@ -60,14 +60,14 @@ export const Log = observer(function Log({navIdx, visible}: ScreenParams) {
style={s.mr5} style={s.mr5}
/> />
) : undefined} ) : undefined}
<Text type="body2" style={[styles.ts, pal.textLight]}> <Text type="sm" style={[styles.ts, pal.textLight]}>
{entry.ts ? ago(entry.ts) : ''} {entry.ts ? ago(entry.ts) : ''}
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
{expanded.includes(entry.id) ? ( {expanded.includes(entry.id) ? (
<View style={[pal.view, s.pl10, s.pr10, s.pb10]}> <View style={[pal.view, s.pl10, s.pr10, s.pb10]}>
<View style={[pal.btn, styles.details]}> <View style={[pal.btn, styles.details]}>
<Text type="mono1" style={pal.text}> <Text type="mono" style={pal.text}>
{entry.details} {entry.details}
</Text> </Text>
</View> </View>

View File

@ -82,7 +82,7 @@ export const Search = ({navIdx, visible, params}: ScreenParams) => {
size={36} size={36}
/> />
<View style={[s.ml10]}> <View style={[s.ml10]}>
<Text type="h5" style={pal.text}> <Text type="title-sm" style={pal.text}>
{item.displayName || item.handle} {item.displayName || item.handle}
</Text> </Text>
<Text style={pal.textLight}>@{item.handle}</Text> <Text style={pal.textLight}>@{item.handle}</Text>

View File

@ -37,7 +37,7 @@ export const Settings = observer(function Settings({
<Text style={pal.text}>Signed in as</Text> <Text style={pal.text}>Signed in as</Text>
<View style={s.flex1} /> <View style={s.flex1} />
<TouchableOpacity onPress={onPressSignout}> <TouchableOpacity onPress={onPressSignout}>
<Text type="h5" style={pal.link}> <Text type="xl-heavy" style={pal.link}>
Sign out Sign out
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>
@ -54,7 +54,7 @@ export const Settings = observer(function Settings({
avatar={store.me.avatar} avatar={store.me.avatar}
/> />
<View style={[s.ml10]}> <View style={[s.ml10]}>
<Text type="h5" style={pal.text}> <Text type="xl-bold" style={pal.text}>
{store.me.displayName || store.me.handle} {store.me.displayName || store.me.handle}
</Text> </Text>
<Text style={pal.textLight}>@{store.me.handle}</Text> <Text style={pal.textLight}>@{store.me.handle}</Text>
@ -62,7 +62,7 @@ export const Settings = observer(function Settings({
</View> </View>
</Link> </Link>
<View style={s.flex1} /> <View style={s.flex1} />
<Text type="overline1" style={[s.mb5]}> <Text type="sm-medium" style={[s.mb5]}>
Advanced Advanced
</Text> </Text>
<Link <Link

View File

@ -74,7 +74,7 @@ export const Menu = observer(
) : undefined} ) : undefined}
</View> </View>
<Text <Text
type="h4" type="title"
style={[ style={[
pal.text, pal.text,
bold ? styles.menuItemLabelBold : styles.menuItemLabel, bold ? styles.menuItemLabelBold : styles.menuItemLabel,
@ -99,7 +99,7 @@ export const Menu = observer(
/> />
<View style={s.flex1}> <View style={s.flex1}>
<Text <Text
type="h3" type="title-lg"
style={[pal.text, styles.profileCardDisplayName]} style={[pal.text, styles.profileCardDisplayName]}
numberOfLines={1}> numberOfLines={1}>
{store.me.displayName || store.me.handle} {store.me.displayName || store.me.handle}
@ -119,7 +119,7 @@ export const Menu = observer(
style={pal.text as StyleProp<ViewStyle>} style={pal.text as StyleProp<ViewStyle>}
size={25} size={25}
/> />
<Text type="h4" style={[pal.text, styles.searchBtnLabel]}> <Text type="title" style={[pal.text, styles.searchBtnLabel]}>
Search Search
</Text> </Text>
</TouchableOpacity> </TouchableOpacity>