rnnovaui 0.1.2 → 0.1.3
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/Button/UIButton.js +118 -190
package/package.json
CHANGED
|
@@ -1,10 +1,16 @@
|
|
|
1
1
|
import React, { memo, useCallback } from "react";
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ActivityIndicator,
|
|
5
|
+
Pressable,
|
|
6
|
+
StyleSheet,
|
|
7
|
+
Text,
|
|
8
|
+
View,
|
|
9
|
+
} from "react-native";
|
|
4
10
|
|
|
5
11
|
import { useUITheme } from "../../theme";
|
|
6
12
|
|
|
7
|
-
const
|
|
13
|
+
const VARIANTS = {
|
|
8
14
|
solid: "solid",
|
|
9
15
|
outline: "outline",
|
|
10
16
|
ghost: "ghost",
|
|
@@ -13,14 +19,14 @@ const BUTTON_VARIANTS = {
|
|
|
13
19
|
success: "success",
|
|
14
20
|
};
|
|
15
21
|
|
|
16
|
-
const
|
|
22
|
+
const SIZES = {
|
|
17
23
|
sm: "sm",
|
|
18
24
|
md: "md",
|
|
19
25
|
lg: "lg",
|
|
20
26
|
xl: "xl",
|
|
21
27
|
};
|
|
22
28
|
|
|
23
|
-
|
|
29
|
+
function UIButtonComponent({
|
|
24
30
|
title,
|
|
25
31
|
children,
|
|
26
32
|
|
|
@@ -31,8 +37,8 @@ const UIButtonComponent = ({
|
|
|
31
37
|
loading = false,
|
|
32
38
|
fullWidth = false,
|
|
33
39
|
|
|
34
|
-
leftIcon
|
|
35
|
-
rightIcon
|
|
40
|
+
leftIcon,
|
|
41
|
+
rightIcon,
|
|
36
42
|
|
|
37
43
|
onPress,
|
|
38
44
|
onLongPress,
|
|
@@ -45,28 +51,33 @@ const UIButtonComponent = ({
|
|
|
45
51
|
|
|
46
52
|
activeOpacity = 0.82,
|
|
47
53
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
hitSlop,
|
|
51
|
-
|
|
54
|
+
testID,
|
|
52
55
|
accessibilityLabel,
|
|
53
56
|
accessibilityHint,
|
|
54
57
|
|
|
55
|
-
testID,
|
|
56
|
-
|
|
57
58
|
...props
|
|
58
|
-
})
|
|
59
|
-
const
|
|
59
|
+
}) {
|
|
60
|
+
const themeResult = useUITheme();
|
|
60
61
|
|
|
61
|
-
|
|
62
|
+
/*
|
|
63
|
+
* Support both possible provider shapes:
|
|
64
|
+
*
|
|
65
|
+
* themeResult.theme.colors
|
|
66
|
+
* themeResult.colors
|
|
67
|
+
*/
|
|
68
|
+
const theme = themeResult?.theme || themeResult || {};
|
|
62
69
|
|
|
63
|
-
const
|
|
70
|
+
const colors = theme.colors || {};
|
|
64
71
|
|
|
65
|
-
const
|
|
72
|
+
const safeVariant = VARIANTS[variant] || VARIANTS.solid;
|
|
66
73
|
|
|
67
|
-
const
|
|
74
|
+
const safeSize = SIZES[size] || SIZES.md;
|
|
68
75
|
|
|
69
|
-
const
|
|
76
|
+
const buttonColors = getButtonColors(safeVariant, colors);
|
|
77
|
+
|
|
78
|
+
const dimensions = getButtonDimensions(safeSize);
|
|
79
|
+
|
|
80
|
+
const isDisabled = disabled || loading;
|
|
70
81
|
|
|
71
82
|
const handlePress = useCallback(
|
|
72
83
|
(event) => {
|
|
@@ -74,9 +85,7 @@ const UIButtonComponent = ({
|
|
|
74
85
|
return;
|
|
75
86
|
}
|
|
76
87
|
|
|
77
|
-
|
|
78
|
-
onPress(event);
|
|
79
|
-
}
|
|
88
|
+
onPress?.(event);
|
|
80
89
|
},
|
|
81
90
|
[isDisabled, onPress],
|
|
82
91
|
);
|
|
@@ -87,9 +96,7 @@ const UIButtonComponent = ({
|
|
|
87
96
|
return;
|
|
88
97
|
}
|
|
89
98
|
|
|
90
|
-
|
|
91
|
-
onLongPress(event);
|
|
92
|
-
}
|
|
99
|
+
onLongPress?.(event);
|
|
93
100
|
},
|
|
94
101
|
[isDisabled, onLongPress],
|
|
95
102
|
);
|
|
@@ -100,9 +107,7 @@ const UIButtonComponent = ({
|
|
|
100
107
|
return;
|
|
101
108
|
}
|
|
102
109
|
|
|
103
|
-
|
|
104
|
-
onPressIn(event);
|
|
105
|
-
}
|
|
110
|
+
onPressIn?.(event);
|
|
106
111
|
},
|
|
107
112
|
[isDisabled, onPressIn],
|
|
108
113
|
);
|
|
@@ -113,20 +118,11 @@ const UIButtonComponent = ({
|
|
|
113
118
|
return;
|
|
114
119
|
}
|
|
115
120
|
|
|
116
|
-
|
|
117
|
-
onPressOut(event);
|
|
118
|
-
}
|
|
121
|
+
onPressOut?.(event);
|
|
119
122
|
},
|
|
120
123
|
[isDisabled, onPressOut],
|
|
121
124
|
);
|
|
122
125
|
|
|
123
|
-
const ripple = android_ripple
|
|
124
|
-
? {
|
|
125
|
-
color: variantStyle.ripple,
|
|
126
|
-
borderless: false,
|
|
127
|
-
}
|
|
128
|
-
: undefined;
|
|
129
|
-
|
|
130
126
|
const hasChildren = children !== undefined && children !== null;
|
|
131
127
|
|
|
132
128
|
return (
|
|
@@ -138,8 +134,6 @@ const UIButtonComponent = ({
|
|
|
138
134
|
onLongPress={handleLongPress}
|
|
139
135
|
onPressIn={handlePressIn}
|
|
140
136
|
onPressOut={handlePressOut}
|
|
141
|
-
hitSlop={hitSlop}
|
|
142
|
-
android_ripple={ripple}
|
|
143
137
|
accessibilityRole="button"
|
|
144
138
|
accessibilityLabel={
|
|
145
139
|
accessibilityLabel || (typeof title === "string" ? title : undefined)
|
|
@@ -153,17 +147,19 @@ const UIButtonComponent = ({
|
|
|
153
147
|
styles.button,
|
|
154
148
|
|
|
155
149
|
{
|
|
156
|
-
|
|
150
|
+
height: dimensions.height,
|
|
157
151
|
|
|
158
|
-
|
|
152
|
+
minHeight: dimensions.height,
|
|
159
153
|
|
|
160
|
-
|
|
154
|
+
paddingHorizontal: dimensions.paddingHorizontal,
|
|
161
155
|
|
|
162
|
-
|
|
156
|
+
borderRadius: dimensions.borderRadius,
|
|
163
157
|
|
|
164
|
-
|
|
158
|
+
backgroundColor: buttonColors.background,
|
|
165
159
|
|
|
166
|
-
|
|
160
|
+
borderColor: buttonColors.border,
|
|
161
|
+
|
|
162
|
+
borderWidth: buttonColors.border ? 1 : 0,
|
|
167
163
|
|
|
168
164
|
width: fullWidth ? "100%" : undefined,
|
|
169
165
|
|
|
@@ -178,236 +174,164 @@ const UIButtonComponent = ({
|
|
|
178
174
|
styles.content,
|
|
179
175
|
|
|
180
176
|
{
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
gap: sizeStyle.gap,
|
|
177
|
+
gap: dimensions.gap,
|
|
184
178
|
},
|
|
185
179
|
|
|
186
180
|
contentStyle,
|
|
187
181
|
]}
|
|
188
182
|
>
|
|
189
183
|
{loading ? (
|
|
190
|
-
<ActivityIndicator size="small" color={
|
|
184
|
+
<ActivityIndicator size="small" color={buttonColors.text} />
|
|
191
185
|
) : leftIcon ? (
|
|
192
|
-
<View style={styles.
|
|
186
|
+
<View style={styles.icon}>{leftIcon}</View>
|
|
193
187
|
) : null}
|
|
194
188
|
|
|
195
189
|
{hasChildren ? (
|
|
196
190
|
<View style={styles.children}>{children}</View>
|
|
197
|
-
) : title
|
|
198
|
-
<
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
191
|
+
) : title ? (
|
|
192
|
+
<Text
|
|
193
|
+
numberOfLines={1}
|
|
194
|
+
style={[
|
|
195
|
+
styles.text,
|
|
196
|
+
|
|
197
|
+
{
|
|
198
|
+
color: buttonColors.text,
|
|
199
|
+
|
|
200
|
+
fontSize: dimensions.fontSize,
|
|
201
|
+
|
|
202
|
+
lineHeight: dimensions.lineHeight,
|
|
203
|
+
},
|
|
204
|
+
|
|
205
|
+
textStyle,
|
|
206
|
+
]}
|
|
202
207
|
>
|
|
203
208
|
{title}
|
|
204
|
-
</
|
|
209
|
+
</Text>
|
|
205
210
|
) : null}
|
|
206
211
|
|
|
207
212
|
{!loading && rightIcon ? (
|
|
208
|
-
<View style={styles.
|
|
213
|
+
<View style={styles.icon}>{rightIcon}</View>
|
|
209
214
|
) : null}
|
|
210
215
|
</View>
|
|
211
216
|
</Pressable>
|
|
212
217
|
);
|
|
213
|
-
};
|
|
214
|
-
|
|
215
|
-
function ButtonText({ children, color, sizeStyle, style }) {
|
|
216
|
-
return (
|
|
217
|
-
<View style={styles.textWrapper}>
|
|
218
|
-
<ButtonTextNative color={color} sizeStyle={sizeStyle} style={style}>
|
|
219
|
-
{children}
|
|
220
|
-
</ButtonTextNative>
|
|
221
|
-
</View>
|
|
222
|
-
);
|
|
223
218
|
}
|
|
224
219
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
color,
|
|
236
|
-
|
|
237
|
-
fontSize: sizeStyle.fontSize,
|
|
238
|
-
|
|
239
|
-
lineHeight: sizeStyle.lineHeight,
|
|
240
|
-
|
|
241
|
-
fontWeight: "600",
|
|
242
|
-
|
|
243
|
-
textAlign: "center",
|
|
244
|
-
},
|
|
245
|
-
|
|
246
|
-
style,
|
|
247
|
-
]}
|
|
248
|
-
>
|
|
249
|
-
{children}
|
|
250
|
-
</Text>
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
function resolveVariant(variant, colors) {
|
|
220
|
+
/**
|
|
221
|
+
* IMPORTANT:
|
|
222
|
+
*
|
|
223
|
+
* Variant resolution is completely independent
|
|
224
|
+
* from spacing/radius/typography.
|
|
225
|
+
*
|
|
226
|
+
* Therefore even if the theme is incomplete,
|
|
227
|
+
* variants still work.
|
|
228
|
+
*/
|
|
229
|
+
function getButtonColors(variant, colors) {
|
|
255
230
|
const primary = colors.primary || "#FF5A1F";
|
|
256
231
|
|
|
257
232
|
const primarySoft = colors.primarySoft || "#FFF0EA";
|
|
258
233
|
|
|
259
|
-
const primaryPressed = colors.primaryPressed || primary;
|
|
260
|
-
|
|
261
234
|
const success = colors.success || "#16A34A";
|
|
262
235
|
|
|
263
236
|
const danger = colors.danger || "#DC2626";
|
|
264
237
|
|
|
265
|
-
const surface = colors.surface || "#F5F5F5";
|
|
266
|
-
|
|
267
|
-
const border = colors.border || "#E5E5E5";
|
|
268
|
-
|
|
269
|
-
const borderStrong = colors.borderStrong || "#D4D4D4";
|
|
270
|
-
|
|
271
238
|
const text = colors.text || "#111111";
|
|
272
239
|
|
|
273
240
|
const onPrimary = colors.onPrimary || "#FFFFFF";
|
|
274
241
|
|
|
242
|
+
const border = colors.border || "#E5E5E5";
|
|
243
|
+
|
|
275
244
|
switch (variant) {
|
|
276
|
-
case
|
|
245
|
+
case VARIANTS.outline:
|
|
277
246
|
return {
|
|
278
|
-
background:
|
|
279
|
-
|
|
247
|
+
background: "transparent",
|
|
280
248
|
border: primary,
|
|
281
|
-
|
|
282
249
|
text: primary,
|
|
283
|
-
|
|
284
|
-
ripple: primarySoft,
|
|
285
250
|
};
|
|
286
251
|
|
|
287
|
-
case
|
|
252
|
+
case VARIANTS.ghost:
|
|
288
253
|
return {
|
|
289
|
-
background:
|
|
290
|
-
|
|
254
|
+
background: "transparent",
|
|
291
255
|
border: null,
|
|
292
|
-
|
|
293
256
|
text: primary,
|
|
294
|
-
|
|
295
|
-
ripple: primarySoft,
|
|
296
257
|
};
|
|
297
258
|
|
|
298
|
-
case
|
|
259
|
+
case VARIANTS.soft:
|
|
299
260
|
return {
|
|
300
261
|
background: primarySoft,
|
|
301
|
-
|
|
302
262
|
border: null,
|
|
303
|
-
|
|
304
263
|
text: primary,
|
|
305
|
-
|
|
306
|
-
ripple: primary,
|
|
307
264
|
};
|
|
308
265
|
|
|
309
|
-
case
|
|
266
|
+
case VARIANTS.danger:
|
|
310
267
|
return {
|
|
311
268
|
background: danger,
|
|
312
|
-
|
|
313
269
|
border: danger,
|
|
314
|
-
|
|
315
270
|
text: onPrimary,
|
|
316
|
-
|
|
317
|
-
ripple: danger,
|
|
318
271
|
};
|
|
319
272
|
|
|
320
|
-
case
|
|
273
|
+
case VARIANTS.success:
|
|
321
274
|
return {
|
|
322
275
|
background: success,
|
|
323
|
-
|
|
324
276
|
border: success,
|
|
325
|
-
|
|
326
277
|
text: onPrimary,
|
|
327
|
-
|
|
328
|
-
ripple: success,
|
|
329
278
|
};
|
|
330
279
|
|
|
331
|
-
case
|
|
280
|
+
case VARIANTS.solid:
|
|
332
281
|
default:
|
|
333
282
|
return {
|
|
334
283
|
background: primary,
|
|
335
|
-
|
|
336
284
|
border: primary,
|
|
337
|
-
|
|
338
285
|
text: onPrimary,
|
|
339
|
-
|
|
340
|
-
ripple: primaryPressed,
|
|
341
286
|
};
|
|
342
287
|
}
|
|
343
288
|
}
|
|
344
289
|
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
290
|
+
/**
|
|
291
|
+
* Sizes intentionally use fixed fallback
|
|
292
|
+
* values so the button cannot break when
|
|
293
|
+
* theme.sizes is missing.
|
|
294
|
+
*/
|
|
295
|
+
function getButtonDimensions(size) {
|
|
352
296
|
switch (size) {
|
|
353
|
-
case
|
|
297
|
+
case SIZES.sm:
|
|
354
298
|
return {
|
|
355
|
-
height:
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
gap: spacing.xs,
|
|
360
|
-
|
|
361
|
-
borderRadius: radius.button,
|
|
362
|
-
|
|
299
|
+
height: 36,
|
|
300
|
+
paddingHorizontal: 14,
|
|
301
|
+
gap: 6,
|
|
302
|
+
borderRadius: 10,
|
|
363
303
|
fontSize: 13,
|
|
364
|
-
|
|
365
304
|
lineHeight: 18,
|
|
366
305
|
};
|
|
367
306
|
|
|
368
|
-
case
|
|
307
|
+
case SIZES.lg:
|
|
369
308
|
return {
|
|
370
|
-
height:
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
gap: spacing.sm,
|
|
375
|
-
|
|
376
|
-
borderRadius: radius.button,
|
|
377
|
-
|
|
309
|
+
height: 52,
|
|
310
|
+
paddingHorizontal: 22,
|
|
311
|
+
gap: 8,
|
|
312
|
+
borderRadius: 14,
|
|
378
313
|
fontSize: 16,
|
|
379
|
-
|
|
380
314
|
lineHeight: 22,
|
|
381
315
|
};
|
|
382
316
|
|
|
383
|
-
case
|
|
317
|
+
case SIZES.xl:
|
|
384
318
|
return {
|
|
385
|
-
height:
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
gap: spacing.sm,
|
|
390
|
-
|
|
391
|
-
borderRadius: radius.button,
|
|
392
|
-
|
|
319
|
+
height: 60,
|
|
320
|
+
paddingHorizontal: 26,
|
|
321
|
+
gap: 8,
|
|
322
|
+
borderRadius: 16,
|
|
393
323
|
fontSize: 17,
|
|
394
|
-
|
|
395
324
|
lineHeight: 24,
|
|
396
325
|
};
|
|
397
326
|
|
|
398
|
-
case
|
|
327
|
+
case SIZES.md:
|
|
399
328
|
default:
|
|
400
329
|
return {
|
|
401
|
-
height:
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
gap: spacing.sm,
|
|
406
|
-
|
|
407
|
-
borderRadius: radius.button,
|
|
408
|
-
|
|
330
|
+
height: 44,
|
|
331
|
+
paddingHorizontal: 18,
|
|
332
|
+
gap: 8,
|
|
333
|
+
borderRadius: 12,
|
|
409
334
|
fontSize: 14,
|
|
410
|
-
|
|
411
335
|
lineHeight: 20,
|
|
412
336
|
};
|
|
413
337
|
}
|
|
@@ -415,14 +339,13 @@ function resolveSize(size, theme) {
|
|
|
415
339
|
|
|
416
340
|
const styles = StyleSheet.create({
|
|
417
341
|
button: {
|
|
342
|
+
flexShrink: 0,
|
|
418
343
|
alignItems: "center",
|
|
419
344
|
justifyContent: "center",
|
|
420
345
|
overflow: "hidden",
|
|
421
|
-
flexShrink: 0,
|
|
422
346
|
},
|
|
423
347
|
|
|
424
348
|
content: {
|
|
425
|
-
width: "100%",
|
|
426
349
|
flexDirection: "row",
|
|
427
350
|
alignItems: "center",
|
|
428
351
|
justifyContent: "center",
|
|
@@ -435,14 +358,17 @@ const styles = StyleSheet.create({
|
|
|
435
358
|
justifyContent: "center",
|
|
436
359
|
},
|
|
437
360
|
|
|
438
|
-
|
|
361
|
+
icon: {
|
|
439
362
|
alignItems: "center",
|
|
440
363
|
justifyContent: "center",
|
|
441
364
|
flexShrink: 0,
|
|
442
365
|
},
|
|
443
366
|
|
|
444
|
-
|
|
367
|
+
text: {
|
|
445
368
|
flexShrink: 1,
|
|
369
|
+
fontWeight: "600",
|
|
370
|
+
textAlign: "center",
|
|
371
|
+
includeFontPadding: false,
|
|
446
372
|
},
|
|
447
373
|
});
|
|
448
374
|
|
|
@@ -450,4 +376,6 @@ export const UIButton = memo(UIButtonComponent);
|
|
|
450
376
|
|
|
451
377
|
UIButton.displayName = "UIButton";
|
|
452
378
|
|
|
453
|
-
export
|
|
379
|
+
export const UIButtonVariants = VARIANTS;
|
|
380
|
+
|
|
381
|
+
export const UIButtonSizes = SIZES;
|