1import { spacing, lightTheme, darkTheme, borderRadius, typography } from '@expo/styleguide-native'; 2import { TextStyle, Platform, StyleSheet } from 'react-native'; 3 4type SpacingKey = `${keyof typeof spacing}`; 5type DescriptiveScale = 'micro' | 'tiny' | 'small' | 'medium' | 'large' | 'xl'; 6type ScaleKey = SpacingKey | DescriptiveScale; 7type Scale = Record<ScaleKey, number>; 8 9export const scale: Scale = { 10 micro: spacing[0.5], 11 tiny: spacing[1], 12 small: spacing[3], 13 medium: spacing[4], 14 large: spacing[6], 15 xl: spacing[8], 16 ...spacing, 17}; 18 19function fullSpacingScaleForAttributes(attributes: string[]) { 20 const obj: { [scaleKey: string]: any } = {}; 21 22 Object.keys(scale).forEach((key) => { 23 key = `${key}`; 24 const value: { [attribute: string]: number } = {}; 25 26 attributes.forEach((attribute) => { 27 value[attribute] = scale[key as ScaleKey]; 28 }); 29 30 obj[key] = value; 31 }); 32 33 return obj as Record<SpacingKey | DescriptiveScale, any>; 34} 35 36export const padding = { 37 padding: fullSpacingScaleForAttributes(['padding']), 38 px: fullSpacingScaleForAttributes(['paddingHorizontal']), 39 py: fullSpacingScaleForAttributes(['paddingVertical']), 40 pb: fullSpacingScaleForAttributes(['paddingBottom']), 41 pt: fullSpacingScaleForAttributes(['paddingTop']), 42}; 43 44export const margin = { 45 margin: fullSpacingScaleForAttributes(['margin']), 46 mx: fullSpacingScaleForAttributes(['marginHorizontal']), 47 my: fullSpacingScaleForAttributes(['marginVertical']), 48 mb: fullSpacingScaleForAttributes(['marginBottom']), 49 mt: fullSpacingScaleForAttributes(['marginTop']), 50}; 51 52export const width = fullSpacingScaleForAttributes(['width']); 53export const height = fullSpacingScaleForAttributes(['height']); 54 55export const rounded = { 56 rounded: { 57 none: { borderRadius: 0 }, 58 small: { borderRadius: borderRadius.small }, 59 medium: { borderRadius: borderRadius.medium }, 60 large: { borderRadius: borderRadius.large }, 61 full: { borderRadius: 99999 }, 62 }, 63 64 roundedTop: { 65 none: { borderTopLeftRadius: 0, borderTopRightRadius: 0 }, 66 small: { borderTopLeftRadius: borderRadius.small, borderTopRightRadius: borderRadius.small }, 67 medium: { 68 borderTopLeftRadius: borderRadius.medium, 69 borderTopRightRadius: borderRadius.medium, 70 }, 71 large: { borderTopLeftRadius: borderRadius.large, borderTopRightRadius: borderRadius.large }, 72 full: { borderTopLeftRadius: 9999, borderTopRightRadius: 9999 }, 73 }, 74 75 roundedBottom: { 76 none: { borderBottomLeftRadius: 0, borderBottomRightRadius: 0 }, 77 small: { 78 borderBottomLeftRadius: borderRadius.small, 79 borderBottomRightRadius: borderRadius.small, 80 }, 81 medium: { 82 borderBottomLeftRadius: borderRadius.medium, 83 borderBottomRightRadius: borderRadius.medium, 84 }, 85 large: { 86 borderBottomLeftRadius: borderRadius.large, 87 borderBottomRightRadius: borderRadius.large, 88 }, 89 full: { borderBottomLeftRadius: 9999, borderBottomRightRadius: 9999 }, 90 }, 91}; 92 93export const text = { 94 align: { 95 center: { textAlign: 'center' as TextStyle['textAlign'] }, 96 }, 97 98 size: { 99 small: typography.fontSizes[12], 100 medium: typography.fontSizes[16], 101 large: typography.fontSizes[18], 102 }, 103 104 leading: { 105 large: { lineHeight: 18 }, 106 }, 107 108 type: { 109 mono: { 110 fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace', 111 }, 112 InterBlack: { fontFamily: 'Inter-Black' }, 113 InterBlackItalic: { fontFamily: 'Inter-BlackItalic' }, 114 InterBold: { fontFamily: 'Inter-Bold' }, 115 InterBoldItalic: { fontFamily: 'Inter-BoldItalic' }, 116 InterExtraBold: { fontFamily: 'Inter-ExtraBold' }, 117 InterExtraBoldItalic: { fontFamily: 'Inter-ExtraBoldItalic' }, 118 InterExtraLight: { fontFamily: 'Inter-ExtraLight' }, 119 InterExtraLightItalic: { fontFamily: 'Inter-ExtraLightItalic' }, 120 InterRegular: { fontFamily: 'Inter-Regular' }, 121 InterItalic: { fontFamily: 'Inter-Italic' }, 122 InterLight: { fontFamily: 'Inter-Light' }, 123 InterLightItalic: { fontFamily: 'Inter-LightItalic' }, 124 InterMedium: { fontFamily: 'Inter-Medium' }, 125 InterMediumItalic: { fontFamily: 'Inter-MediumItalic' }, 126 InterSemiBold: { fontFamily: 'Inter-SemiBold' }, 127 InterSemiBoldItalic: { fontFamily: 'Inter-SemiBoldItalic' }, 128 InterThin: { fontFamily: 'Inter-Thin' }, 129 InterThinItalic: { fontFamily: 'Inter-ThinItalic' }, 130 }, 131 132 weight: { 133 thin: { fontFamily: 'Inter-Thin' }, 134 extralight: { fontFamily: 'Inter-ExtraLight' }, 135 light: { fontFamily: 'Inter-Light' }, 136 normal: { fontFamily: 'Inter-Regular' }, 137 medium: { fontFamily: 'Inter-Medium' }, 138 semibold: { fontFamily: 'Inter-SemiBold' }, 139 bold: { fontFamily: 'Inter-Bold' }, 140 extrabold: { fontFamily: 'Inter-ExtraBold' }, 141 black: { fontFamily: 'Inter-Black' }, 142 }, 143 144 color: { 145 default: { color: lightTheme.text.default }, 146 error: { color: lightTheme.text.error }, 147 warning: { color: lightTheme.text.warning }, 148 success: { color: lightTheme.text.success }, 149 secondary: { color: lightTheme.text.secondary }, 150 primary: { color: lightTheme.button.primary.background }, 151 link: { color: lightTheme.link.default }, 152 }, 153}; 154 155export const textDark = { 156 base: { 157 color: darkTheme.text.default, 158 }, 159 160 color: { 161 default: { color: darkTheme.text.default }, 162 error: { color: darkTheme.text.error }, 163 warning: { color: darkTheme.text.warning }, 164 success: { color: darkTheme.text.success }, 165 secondary: { color: darkTheme.text.secondary }, 166 primary: { color: darkTheme.button.primary.background }, 167 link: { color: darkTheme.link.default }, 168 }, 169}; 170 171export const bg = { 172 none: { backgroundColor: 'transparent' }, 173 default: { backgroundColor: lightTheme.background.default }, 174 secondary: { backgroundColor: lightTheme.background.secondary }, 175 overlay: { backgroundColor: lightTheme.background.overlay }, 176 success: { backgroundColor: lightTheme.background.success }, 177 warning: { backgroundColor: lightTheme.background.warning }, 178 error: { backgroundColor: lightTheme.background.error }, 179}; 180 181export const bgDark = { 182 default: { backgroundColor: darkTheme.background.default }, 183 secondary: { backgroundColor: darkTheme.background.secondary }, 184 overlay: { backgroundColor: darkTheme.background.overlay }, 185 success: { backgroundColor: darkTheme.background.success }, 186 warning: { backgroundColor: darkTheme.background.warning }, 187 error: { backgroundColor: darkTheme.background.error }, 188}; 189 190type NavigationTheme = { 191 dark: boolean; 192 colors: { 193 primary: string; 194 background: string; 195 card: string; 196 text: string; 197 border: string; 198 notification: string; 199 }; 200}; 201 202export const lightNavigationTheme: NavigationTheme = { 203 dark: false, 204 colors: { 205 primary: lightTheme.button.primary.background, 206 background: lightTheme.background.screen, 207 card: lightTheme.background.default, 208 text: lightTheme.text.default, 209 border: lightTheme.border.default, 210 notification: lightTheme.highlight.accent, 211 }, 212}; 213 214export const darkNavigationTheme: NavigationTheme = { 215 dark: true, 216 colors: { 217 primary: darkTheme.link.default, 218 background: darkTheme.background.screen, 219 card: darkTheme.background.screen, 220 text: darkTheme.text.default, 221 border: darkTheme.border.default, 222 notification: darkTheme.highlight.accent, 223 }, 224}; 225 226export const border = { 227 default: { borderColor: lightTheme.border.default, borderWidth: 1 }, 228 warning: { borderColor: lightTheme.border.warning, borderWidth: 1 }, 229 hairline: { borderColor: lightTheme.border.default, borderWidth: StyleSheet.hairlineWidth }, 230}; 231 232export const borderDark = { 233 default: { borderColor: darkTheme.border.default, borderWidth: 1 }, 234 warning: { borderColor: darkTheme.border.warning, borderWidth: 1 }, 235 error: { borderColor: darkTheme.border.error, borderWidth: 1 }, 236 hairline: { borderColor: darkTheme.border.default, borderWidth: StyleSheet.hairlineWidth }, 237}; 238