rnnovaui 0.4.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/components/Avatar/UIAvatar.js +386 -0
- package/src/components/Avatar/index.js +6 -0
- package/src/components/Checkbox/UICheckbox.js +382 -0
- package/src/components/Checkbox/index.js +1 -0
- package/src/components/Input/UIInput.js +683 -0
- package/src/components/Input/index.js +6 -0
- package/src/components/Radio/UIRadio.js +364 -0
- package/src/components/Radio/index.js +1 -0
- package/src/components/Switch/UISwitch.js +337 -0
- package/src/components/Switch/index.js +1 -0
- package/src/components/index.js +10 -0
- package/src/index.js +17 -0
package/package.json
CHANGED
|
@@ -0,0 +1,386 @@
|
|
|
1
|
+
import React, { memo, useMemo } from "react";
|
|
2
|
+
|
|
3
|
+
import { ActivityIndicator, Image, StyleSheet, Text, View } from "react-native";
|
|
4
|
+
|
|
5
|
+
import { useUITheme } from "../../theme";
|
|
6
|
+
|
|
7
|
+
const AVATAR_SIZES = {
|
|
8
|
+
xs: "xs",
|
|
9
|
+
sm: "sm",
|
|
10
|
+
md: "md",
|
|
11
|
+
lg: "lg",
|
|
12
|
+
xl: "xl",
|
|
13
|
+
xxl: "xxl",
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
const AVATAR_VARIANTS = {
|
|
17
|
+
circle: "circle",
|
|
18
|
+
rounded: "rounded",
|
|
19
|
+
square: "square",
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
const AVATAR_STATUS = {
|
|
23
|
+
online: "online",
|
|
24
|
+
offline: "offline",
|
|
25
|
+
busy: "busy",
|
|
26
|
+
away: "away",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
const AVATAR_FALLBACK_COLORS = {
|
|
30
|
+
primary: "#FF5A1F",
|
|
31
|
+
secondary: "#7CFF32",
|
|
32
|
+
white: "#FFFFFF",
|
|
33
|
+
text: "#111111",
|
|
34
|
+
textSecondary: "#525252",
|
|
35
|
+
border: "#E5E5E5",
|
|
36
|
+
success: "#16A34A",
|
|
37
|
+
danger: "#DC2626",
|
|
38
|
+
warning: "#D97706",
|
|
39
|
+
muted: "#737373",
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
function UIAvatarComponent({
|
|
43
|
+
source,
|
|
44
|
+
|
|
45
|
+
uri,
|
|
46
|
+
|
|
47
|
+
name,
|
|
48
|
+
|
|
49
|
+
initials,
|
|
50
|
+
|
|
51
|
+
icon,
|
|
52
|
+
|
|
53
|
+
size = "md",
|
|
54
|
+
|
|
55
|
+
variant = "circle",
|
|
56
|
+
|
|
57
|
+
backgroundColor,
|
|
58
|
+
|
|
59
|
+
textColor,
|
|
60
|
+
|
|
61
|
+
borderColor,
|
|
62
|
+
|
|
63
|
+
borderWidth = 0,
|
|
64
|
+
|
|
65
|
+
status,
|
|
66
|
+
|
|
67
|
+
statusColor,
|
|
68
|
+
|
|
69
|
+
statusSize,
|
|
70
|
+
|
|
71
|
+
loading = false,
|
|
72
|
+
|
|
73
|
+
fallback = true,
|
|
74
|
+
|
|
75
|
+
style,
|
|
76
|
+
|
|
77
|
+
imageStyle,
|
|
78
|
+
|
|
79
|
+
textStyle,
|
|
80
|
+
|
|
81
|
+
iconContainerStyle,
|
|
82
|
+
|
|
83
|
+
statusStyle,
|
|
84
|
+
|
|
85
|
+
testID,
|
|
86
|
+
|
|
87
|
+
...props
|
|
88
|
+
}) {
|
|
89
|
+
const { theme } = useUITheme();
|
|
90
|
+
|
|
91
|
+
const colors = theme?.colors || {};
|
|
92
|
+
|
|
93
|
+
const safeSize = AVATAR_SIZES[size] ? size : AVATAR_SIZES.md;
|
|
94
|
+
|
|
95
|
+
const safeVariant = AVATAR_VARIANTS[variant]
|
|
96
|
+
? variant
|
|
97
|
+
: AVATAR_VARIANTS.circle;
|
|
98
|
+
|
|
99
|
+
const dimensions = useMemo(() => getDimensions(safeSize), [safeSize]);
|
|
100
|
+
|
|
101
|
+
const radius = useMemo(
|
|
102
|
+
() => getRadius(safeVariant, dimensions.size, theme),
|
|
103
|
+
[safeVariant, dimensions.size, theme],
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
const resolvedBackground =
|
|
107
|
+
backgroundColor || colors.primary || AVATAR_FALLBACK_COLORS.primary;
|
|
108
|
+
|
|
109
|
+
const resolvedTextColor =
|
|
110
|
+
textColor || colors.onPrimary || AVATAR_FALLBACK_COLORS.white;
|
|
111
|
+
|
|
112
|
+
const resolvedBorder =
|
|
113
|
+
borderColor || colors.border || AVATAR_FALLBACK_COLORS.border;
|
|
114
|
+
|
|
115
|
+
const imageSource = source || (uri ? { uri } : null);
|
|
116
|
+
|
|
117
|
+
const resolvedInitials = initials || getInitials(name);
|
|
118
|
+
|
|
119
|
+
const resolvedStatusColor = statusColor || getStatusColor(status, colors);
|
|
120
|
+
|
|
121
|
+
const resolvedStatusSize = statusSize || dimensions.statusSize;
|
|
122
|
+
|
|
123
|
+
const shouldShowFallback = fallback && !imageSource;
|
|
124
|
+
|
|
125
|
+
return (
|
|
126
|
+
<View
|
|
127
|
+
{...props}
|
|
128
|
+
testID={testID}
|
|
129
|
+
style={[
|
|
130
|
+
styles.wrapper,
|
|
131
|
+
|
|
132
|
+
{
|
|
133
|
+
width: dimensions.size,
|
|
134
|
+
|
|
135
|
+
height: dimensions.size,
|
|
136
|
+
},
|
|
137
|
+
|
|
138
|
+
style,
|
|
139
|
+
]}
|
|
140
|
+
>
|
|
141
|
+
<View
|
|
142
|
+
style={[
|
|
143
|
+
styles.avatar,
|
|
144
|
+
|
|
145
|
+
{
|
|
146
|
+
width: dimensions.size,
|
|
147
|
+
|
|
148
|
+
height: dimensions.size,
|
|
149
|
+
|
|
150
|
+
borderRadius: radius,
|
|
151
|
+
|
|
152
|
+
backgroundColor: resolvedBackground,
|
|
153
|
+
|
|
154
|
+
borderColor: resolvedBorder,
|
|
155
|
+
|
|
156
|
+
borderWidth,
|
|
157
|
+
},
|
|
158
|
+
]}
|
|
159
|
+
>
|
|
160
|
+
{loading ? (
|
|
161
|
+
<ActivityIndicator size="small" color={resolvedTextColor} />
|
|
162
|
+
) : imageSource ? (
|
|
163
|
+
<Image
|
|
164
|
+
source={imageSource}
|
|
165
|
+
resizeMode="cover"
|
|
166
|
+
style={[
|
|
167
|
+
styles.image,
|
|
168
|
+
|
|
169
|
+
{
|
|
170
|
+
borderRadius: radius,
|
|
171
|
+
},
|
|
172
|
+
|
|
173
|
+
imageStyle,
|
|
174
|
+
]}
|
|
175
|
+
/>
|
|
176
|
+
) : shouldShowFallback ? (
|
|
177
|
+
<Text
|
|
178
|
+
numberOfLines={1}
|
|
179
|
+
style={[
|
|
180
|
+
styles.initials,
|
|
181
|
+
|
|
182
|
+
{
|
|
183
|
+
color: resolvedTextColor,
|
|
184
|
+
|
|
185
|
+
fontSize: dimensions.fontSize,
|
|
186
|
+
|
|
187
|
+
lineHeight: dimensions.fontSize + 4,
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
textStyle,
|
|
191
|
+
]}
|
|
192
|
+
>
|
|
193
|
+
{resolvedInitials}
|
|
194
|
+
</Text>
|
|
195
|
+
) : icon ? (
|
|
196
|
+
<View style={[styles.iconContainer, iconContainerStyle]}>{icon}</View>
|
|
197
|
+
) : null}
|
|
198
|
+
</View>
|
|
199
|
+
|
|
200
|
+
{status ? (
|
|
201
|
+
<View
|
|
202
|
+
style={[
|
|
203
|
+
styles.status,
|
|
204
|
+
|
|
205
|
+
{
|
|
206
|
+
width: resolvedStatusSize,
|
|
207
|
+
|
|
208
|
+
height: resolvedStatusSize,
|
|
209
|
+
|
|
210
|
+
borderRadius: resolvedStatusSize / 2,
|
|
211
|
+
|
|
212
|
+
backgroundColor: resolvedStatusColor,
|
|
213
|
+
|
|
214
|
+
borderColor:
|
|
215
|
+
colors.card ||
|
|
216
|
+
colors.background ||
|
|
217
|
+
AVATAR_FALLBACK_COLORS.white,
|
|
218
|
+
|
|
219
|
+
borderWidth: 2,
|
|
220
|
+
},
|
|
221
|
+
|
|
222
|
+
statusStyle,
|
|
223
|
+
]}
|
|
224
|
+
/>
|
|
225
|
+
) : null}
|
|
226
|
+
</View>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function getInitials(name) {
|
|
231
|
+
if (!name) {
|
|
232
|
+
return "?";
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
const parts = String(name).trim().split(/\s+/).filter(Boolean);
|
|
236
|
+
|
|
237
|
+
if (parts.length === 1) {
|
|
238
|
+
return parts[0].slice(0, 2).toUpperCase();
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function getDimensions(size) {
|
|
245
|
+
switch (size) {
|
|
246
|
+
case AVATAR_SIZES.xs:
|
|
247
|
+
return {
|
|
248
|
+
size: 28,
|
|
249
|
+
fontSize: 10,
|
|
250
|
+
statusSize: 8,
|
|
251
|
+
};
|
|
252
|
+
|
|
253
|
+
case AVATAR_SIZES.sm:
|
|
254
|
+
return {
|
|
255
|
+
size: 36,
|
|
256
|
+
fontSize: 12,
|
|
257
|
+
statusSize: 10,
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
case AVATAR_SIZES.lg:
|
|
261
|
+
return {
|
|
262
|
+
size: 64,
|
|
263
|
+
fontSize: 20,
|
|
264
|
+
statusSize: 16,
|
|
265
|
+
};
|
|
266
|
+
|
|
267
|
+
case AVATAR_SIZES.xl:
|
|
268
|
+
return {
|
|
269
|
+
size: 80,
|
|
270
|
+
fontSize: 24,
|
|
271
|
+
statusSize: 18,
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
case AVATAR_SIZES.xxl:
|
|
275
|
+
return {
|
|
276
|
+
size: 104,
|
|
277
|
+
fontSize: 30,
|
|
278
|
+
statusSize: 22,
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
case AVATAR_SIZES.md:
|
|
282
|
+
default:
|
|
283
|
+
return {
|
|
284
|
+
size: 48,
|
|
285
|
+
fontSize: 16,
|
|
286
|
+
statusSize: 13,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
function getRadius(variant, size, theme) {
|
|
292
|
+
switch (variant) {
|
|
293
|
+
case AVATAR_VARIANTS.square:
|
|
294
|
+
return theme?.radius?.sm ?? 8;
|
|
295
|
+
|
|
296
|
+
case AVATAR_VARIANTS.rounded:
|
|
297
|
+
return theme?.radius?.md ?? 12;
|
|
298
|
+
|
|
299
|
+
case AVATAR_VARIANTS.circle:
|
|
300
|
+
default:
|
|
301
|
+
return size / 2;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
function getStatusColor(status, colors) {
|
|
306
|
+
switch (status) {
|
|
307
|
+
case AVATAR_STATUS.online:
|
|
308
|
+
return colors.success || AVATAR_FALLBACK_COLORS.success;
|
|
309
|
+
|
|
310
|
+
case AVATAR_STATUS.busy:
|
|
311
|
+
return colors.danger || AVATAR_FALLBACK_COLORS.danger;
|
|
312
|
+
|
|
313
|
+
case AVATAR_STATUS.away:
|
|
314
|
+
return colors.warning || AVATAR_FALLBACK_COLORS.warning;
|
|
315
|
+
|
|
316
|
+
case AVATAR_STATUS.offline:
|
|
317
|
+
return colors.textMuted || AVATAR_FALLBACK_COLORS.muted;
|
|
318
|
+
|
|
319
|
+
default:
|
|
320
|
+
return colors.success || AVATAR_FALLBACK_COLORS.success;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
const styles = StyleSheet.create({
|
|
325
|
+
wrapper: {
|
|
326
|
+
position: "relative",
|
|
327
|
+
|
|
328
|
+
flexShrink: 0,
|
|
329
|
+
},
|
|
330
|
+
|
|
331
|
+
avatar: {
|
|
332
|
+
alignItems: "center",
|
|
333
|
+
|
|
334
|
+
justifyContent: "center",
|
|
335
|
+
|
|
336
|
+
overflow: "hidden",
|
|
337
|
+
},
|
|
338
|
+
|
|
339
|
+
image: {
|
|
340
|
+
width: "100%",
|
|
341
|
+
|
|
342
|
+
height: "100%",
|
|
343
|
+
},
|
|
344
|
+
|
|
345
|
+
initials: {
|
|
346
|
+
fontWeight: "700",
|
|
347
|
+
|
|
348
|
+
includeFontPadding: false,
|
|
349
|
+
|
|
350
|
+
textAlign: "center",
|
|
351
|
+
|
|
352
|
+
textTransform: "uppercase",
|
|
353
|
+
},
|
|
354
|
+
|
|
355
|
+
iconContainer: {
|
|
356
|
+
alignItems: "center",
|
|
357
|
+
|
|
358
|
+
justifyContent: "center",
|
|
359
|
+
|
|
360
|
+
width: "100%",
|
|
361
|
+
|
|
362
|
+
height: "100%",
|
|
363
|
+
},
|
|
364
|
+
|
|
365
|
+
status: {
|
|
366
|
+
position: "absolute",
|
|
367
|
+
|
|
368
|
+
right: -1,
|
|
369
|
+
|
|
370
|
+
bottom: -1,
|
|
371
|
+
|
|
372
|
+
zIndex: 10,
|
|
373
|
+
},
|
|
374
|
+
});
|
|
375
|
+
|
|
376
|
+
export const UIAvatar = memo(UIAvatarComponent);
|
|
377
|
+
|
|
378
|
+
UIAvatar.displayName = "UIAvatar";
|
|
379
|
+
|
|
380
|
+
export {
|
|
381
|
+
AVATAR_SIZES as UIAvatarSizes,
|
|
382
|
+
AVATAR_VARIANTS as UIAvatarVariants,
|
|
383
|
+
AVATAR_STATUS as UIAvatarStatus,
|
|
384
|
+
};
|
|
385
|
+
|
|
386
|
+
export default UIAvatar;
|