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