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