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    size: {
180      micro: { width: scale.micro, flex: 0 },
181      tiny: { width: scale.tiny, flex: 0 },
182      small: { width: scale.small, flex: 0 },
183      medium: { width: scale.medium, flex: 0 },
184      large: { width: scale.large, flex: 0 },
185      xl: { width: scale.xl, flex: 0 },
186    },
187  },
188});
189
190const Vertical = create(RNView, {
191  base: {
192    flex: 1,
193  },
194  variants: {
195    size: {
196      micro: { height: scale.micro, flex: 0 },
197      tiny: { height: scale.tiny, flex: 0 },
198      small: { height: scale.small, flex: 0 },
199      medium: { height: scale.medium, flex: 0 },
200      large: { height: scale.large, flex: 0 },
201      xl: { height: scale.xl, flex: 0 },
202    },
203  },
204});
205
206export const Spacer = {
207  Vertical,
208  Horizontal,
209};
210
211export const Divider = create(RNView, {
212  base: {
213    height: StyleSheet.hairlineWidth,
214    backgroundColor: lightTheme.border.default,
215  },
216
217  variants: {
218    weight: {
219      thin: { height: StyleSheet.hairlineWidth },
220      normal: { height: 1 },
221      heavy: { height: 2 },
222    },
223
224    ...margin,
225  },
226
227  selectors: {
228    dark: {
229      base: {
230        height: StyleSheet.hairlineWidth,
231        backgroundColor: darkTheme.border.default,
232      },
233    },
234  },
235});
236
237export const StatusIndicator = create(RNView, {
238  base: {
239    backgroundColor: lightTheme.status.default,
240    borderRadius: 9999,
241  },
242
243  variants: {
244    status: {
245      info: { backgroundColor: lightTheme.status.info },
246      success: { backgroundColor: lightTheme.status.success },
247      warning: { backgroundColor: lightTheme.status.warning },
248      error: { backgroundColor: lightTheme.status.error },
249      default: { backgroundColor: lightTheme.status.default },
250    },
251
252    size: {
253      small: {
254        width: scale.small,
255        height: scale.small,
256      },
257      medium: {
258        width: scale.medium,
259        height: scale.medium,
260      },
261    },
262  },
263
264  selectors: {
265    dark: {
266      info: { backgroundColor: darkTheme.status.info },
267      success: { backgroundColor: darkTheme.status.success },
268      warning: { backgroundColor: darkTheme.status.warning },
269      error: { backgroundColor: darkTheme.status.error },
270      default: { backgroundColor: darkTheme.status.default },
271    },
272  },
273});
274