1import { lightTheme, darkTheme, shadows } from '@expo/styleguide-native'; 2import { View as RNView, StyleSheet } from 'react-native'; 3 4import { create } from './create-primitive'; 5import { 6 scale, 7 padding, 8 margin, 9 rounded, 10 bg, 11 bgDark, 12 width, 13 height, 14 borderDark, 15 border, 16} from './theme'; 17 18export const View = create(RNView, { 19 variants: { 20 overflow: { 21 hidden: { 22 overflow: 'hidden', 23 }, 24 }, 25 26 align: { 27 centered: { 28 justifyContent: 'center', 29 alignItems: 'center', 30 }, 31 start: { 32 alignItems: 'flex-start', 33 }, 34 }, 35 36 flex: { 37 '1': { flex: 1 }, 38 '0': { flex: 0 }, 39 }, 40 41 shrink: { 42 '1': { flexShrink: 1 }, 43 '0': { flexShrink: 0 }, 44 }, 45 46 grow: { 47 '1': { flexGrow: 1 }, 48 '0': { flexGrow: 0 }, 49 }, 50 51 bg, 52 53 opacity: { 54 '1': { opacity: 1 }, 55 '0.5': { opacity: 0.5 }, 56 '0.75': { opacity: 0.75 }, 57 '0': { opacity: 0 }, 58 }, 59 60 inset: { 61 top: { 62 position: 'absolute', 63 top: 0, 64 left: 0, 65 right: 0, 66 }, 67 68 bottom: { 69 position: 'absolute', 70 bottom: 0, 71 left: 0, 72 right: 0, 73 }, 74 75 full: { 76 position: 'absolute', 77 top: 0, 78 left: 0, 79 right: 0, 80 bottom: 0, 81 }, 82 }, 83 84 border: { 85 default: { borderColor: lightTheme.border.default, borderWidth: 1 }, 86 hairline: { borderColor: lightTheme.border.default, borderWidth: StyleSheet.hairlineWidth }, 87 warning: { borderColor: lightTheme.border.warning, borderWidth: 1 }, 88 error: { borderColor: lightTheme.border.error, borderWidth: 1 }, 89 }, 90 91 ...rounded, 92 93 shadow: { 94 micro: shadows.micro, 95 tiny: shadows.tiny, 96 small: shadows.small, 97 medium: shadows.medium, 98 button: shadows.button, 99 }, 100 101 width, 102 height, 103 104 ...padding, 105 ...margin, 106 }, 107 108 selectors: { 109 dark: { 110 bg: bgDark, 111 112 border: borderDark, 113 }, 114 115 light: { 116 bg: {}, 117 }, 118 }, 119}); 120 121export const Row = create(RNView, { 122 base: { 123 flexDirection: 'row', 124 }, 125 126 variants: { 127 bg, 128 129 flex: { 130 '1': { flex: 1 }, 131 '0': { flex: 0 }, 132 }, 133 134 shrink: { 135 '1': { flexShrink: 1 }, 136 '0': { flexShrink: 0 }, 137 }, 138 139 grow: { 140 '1': { flexGrow: 1 }, 141 '0': { flexGrow: 0 }, 142 }, 143 144 align: { 145 center: { alignItems: 'center' }, 146 start: { alignItems: 'flex-start' }, 147 end: { alignItems: 'flex-end' }, 148 }, 149 150 justify: { 151 center: { justifyContent: 'center' }, 152 start: { justifyContent: 'flex-start' }, 153 end: { justifyContent: 'flex-end' }, 154 between: { justifyContent: 'space-between' }, 155 around: { justifyContent: 'space-around' }, 156 }, 157 158 ...padding, 159 ...margin, 160 161 ...rounded, 162 163 border, 164 }, 165 166 selectors: { 167 dark: { 168 bg: bgDark, 169 border: borderDark, 170 }, 171 }, 172}); 173 174const Horizontal = create(RNView, { 175 base: { 176 flex: 1, 177 }, 178 variants: { 179 bg, 180 size: { 181 micro: { width: scale.micro, flex: 0 }, 182 tiny: { width: scale.tiny, flex: 0 }, 183 small: { width: scale.small, flex: 0 }, 184 medium: { width: scale.medium, flex: 0 }, 185 large: { width: scale.large, flex: 0 }, 186 xl: { width: scale.xl, flex: 0 }, 187 }, 188 }, 189 190 selectors: { 191 dark: { 192 bg: bgDark, 193 }, 194 }, 195}); 196 197const Vertical = create(RNView, { 198 base: { 199 flex: 1, 200 }, 201 variants: { 202 bg, 203 size: { 204 micro: { height: scale.micro, flex: 0 }, 205 tiny: { height: scale.tiny, flex: 0 }, 206 small: { height: scale.small, flex: 0 }, 207 medium: { height: scale.medium, flex: 0 }, 208 large: { height: scale.large, flex: 0 }, 209 xl: { height: scale.xl, flex: 0 }, 210 }, 211 }, 212 213 selectors: { 214 dark: { 215 bg: bgDark, 216 }, 217 }, 218}); 219 220export const Spacer = { 221 Vertical, 222 Horizontal, 223}; 224 225export const Divider = create(RNView, { 226 base: { 227 height: StyleSheet.hairlineWidth, 228 backgroundColor: lightTheme.border.default, 229 }, 230 231 variants: { 232 weight: { 233 thin: { height: StyleSheet.hairlineWidth }, 234 normal: { height: 1 }, 235 heavy: { height: 2 }, 236 }, 237 238 ...margin, 239 }, 240 241 selectors: { 242 dark: { 243 base: { 244 height: StyleSheet.hairlineWidth, 245 backgroundColor: darkTheme.border.default, 246 }, 247 }, 248 }, 249}); 250 251export const StatusIndicator = create(RNView, { 252 base: { 253 backgroundColor: lightTheme.status.default, 254 borderRadius: 9999, 255 }, 256 257 variants: { 258 status: { 259 info: { backgroundColor: lightTheme.status.info }, 260 success: { backgroundColor: lightTheme.status.success }, 261 warning: { backgroundColor: lightTheme.status.warning }, 262 error: { backgroundColor: lightTheme.status.error }, 263 default: { backgroundColor: lightTheme.status.default }, 264 }, 265 266 size: { 267 small: { 268 width: scale.small, 269 height: scale.small, 270 }, 271 medium: { 272 width: scale.medium, 273 height: scale.medium, 274 }, 275 }, 276 }, 277 278 selectors: { 279 dark: { 280 info: { backgroundColor: darkTheme.status.info }, 281 success: { backgroundColor: darkTheme.status.success }, 282 warning: { backgroundColor: darkTheme.status.warning }, 283 error: { backgroundColor: darkTheme.status.error }, 284 default: { backgroundColor: darkTheme.status.default }, 285 }, 286 }, 287}); 288