1import { spacing, lightTheme, darkTheme, borderRadius } from '@expo/styleguide-native'; 2import { TextStyle } 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: 'Menlo', 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 }, 142}; 143 144export const textDark = { 145 base: { 146 color: darkTheme.text.default, 147 }, 148 149 color: { 150 default: { color: darkTheme.text.default }, 151 error: { color: darkTheme.text.error }, 152 warning: { color: darkTheme.text.warning }, 153 success: { color: darkTheme.text.success }, 154 secondary: { color: darkTheme.text.secondary }, 155 primary: { color: darkTheme.button.primary.background }, 156 }, 157}; 158 159export const bg = { 160 none: { backgroundColor: 'transparent' }, 161 default: { backgroundColor: lightTheme.background.default }, 162 secondary: { backgroundColor: lightTheme.background.secondary }, 163 success: { backgroundColor: lightTheme.background.success }, 164 warning: { backgroundColor: lightTheme.background.warning }, 165 error: { backgroundColor: lightTheme.background.error }, 166}; 167 168export const bgDark = { 169 default: { backgroundColor: darkTheme.background.default }, 170 secondary: { backgroundColor: darkTheme.background.secondary }, 171 success: { backgroundColor: darkTheme.background.success }, 172 warning: { backgroundColor: darkTheme.background.warning }, 173 error: { backgroundColor: darkTheme.background.error }, 174}; 175 176type NavigationTheme = { 177 dark: boolean; 178 colors: { 179 primary: string; 180 background: string; 181 card: string; 182 text: string; 183 border: string; 184 notification: string; 185 }; 186}; 187 188export const lightNavigationTheme: NavigationTheme = { 189 dark: false, 190 colors: { 191 primary: lightTheme.button.primary.background, 192 background: lightTheme.background.secondary, 193 card: lightTheme.background.default, 194 text: lightTheme.text.default, 195 border: lightTheme.border.default, 196 notification: lightTheme.highlight.accent, 197 }, 198}; 199 200export const darkNavigationTheme: NavigationTheme = { 201 dark: true, 202 colors: { 203 primary: darkTheme.button.primary.background, 204 background: darkTheme.background.secondary, 205 card: darkTheme.background.default, 206 text: darkTheme.text.default, 207 border: darkTheme.border.default, 208 notification: darkTheme.highlight.accent, 209 }, 210}; 211