rnnovaui 0.1.1 → 0.1.2
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 +163 -115
package/package.json
CHANGED
|
@@ -4,8 +4,6 @@ import { ActivityIndicator, Pressable, StyleSheet, View } from "react-native";
|
|
|
4
4
|
|
|
5
5
|
import { useUITheme } from "../../theme";
|
|
6
6
|
|
|
7
|
-
import { UIText } from "../Text";
|
|
8
|
-
|
|
9
7
|
const BUTTON_VARIANTS = {
|
|
10
8
|
solid: "solid",
|
|
11
9
|
outline: "outline",
|
|
@@ -24,68 +22,51 @@ const BUTTON_SIZES = {
|
|
|
24
22
|
|
|
25
23
|
const UIButtonComponent = ({
|
|
26
24
|
title,
|
|
27
|
-
|
|
28
25
|
children,
|
|
29
26
|
|
|
30
27
|
variant = "solid",
|
|
31
|
-
|
|
32
28
|
size = "md",
|
|
33
29
|
|
|
34
30
|
disabled = false,
|
|
35
|
-
|
|
36
31
|
loading = false,
|
|
37
|
-
|
|
38
32
|
fullWidth = false,
|
|
39
33
|
|
|
40
34
|
leftIcon = null,
|
|
41
|
-
|
|
42
35
|
rightIcon = null,
|
|
43
36
|
|
|
44
37
|
onPress,
|
|
45
|
-
|
|
46
38
|
onLongPress,
|
|
47
|
-
|
|
48
39
|
onPressIn,
|
|
49
|
-
|
|
50
40
|
onPressOut,
|
|
51
41
|
|
|
52
42
|
style,
|
|
53
|
-
|
|
54
43
|
contentStyle,
|
|
55
|
-
|
|
56
44
|
textStyle,
|
|
57
45
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
accessibilityLabel,
|
|
61
|
-
|
|
62
|
-
accessibilityHint,
|
|
46
|
+
activeOpacity = 0.82,
|
|
63
47
|
|
|
64
|
-
|
|
48
|
+
android_ripple = true,
|
|
65
49
|
|
|
66
50
|
hitSlop,
|
|
67
51
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
android_ripple = true,
|
|
52
|
+
accessibilityLabel,
|
|
53
|
+
accessibilityHint,
|
|
71
54
|
|
|
72
|
-
|
|
55
|
+
testID,
|
|
73
56
|
|
|
74
57
|
...props
|
|
75
58
|
}) => {
|
|
76
59
|
const { theme } = useUITheme();
|
|
77
60
|
|
|
78
|
-
const safeVariant = BUTTON_VARIANTS[variant]
|
|
79
|
-
? variant
|
|
80
|
-
: BUTTON_VARIANTS.solid;
|
|
61
|
+
const safeVariant = BUTTON_VARIANTS[variant] || BUTTON_VARIANTS.solid;
|
|
81
62
|
|
|
82
|
-
const safeSize = BUTTON_SIZES[size]
|
|
63
|
+
const safeSize = BUTTON_SIZES[size] || BUTTON_SIZES.md;
|
|
83
64
|
|
|
84
|
-
const isDisabled =
|
|
65
|
+
const isDisabled = disabled || loading;
|
|
85
66
|
|
|
86
|
-
const
|
|
67
|
+
const variantStyle = resolveVariant(safeVariant, theme.colors);
|
|
87
68
|
|
|
88
|
-
const
|
|
69
|
+
const sizeStyle = resolveSize(safeSize, theme);
|
|
89
70
|
|
|
90
71
|
const handlePress = useCallback(
|
|
91
72
|
(event) => {
|
|
@@ -141,25 +122,12 @@ const UIButtonComponent = ({
|
|
|
141
122
|
|
|
142
123
|
const ripple = android_ripple
|
|
143
124
|
? {
|
|
144
|
-
color:
|
|
125
|
+
color: variantStyle.ripple,
|
|
145
126
|
borderless: false,
|
|
146
127
|
}
|
|
147
128
|
: undefined;
|
|
148
129
|
|
|
149
|
-
|
|
150
|
-
* Important:
|
|
151
|
-
*
|
|
152
|
-
* title = text
|
|
153
|
-
*
|
|
154
|
-
* children = arbitrary JSX
|
|
155
|
-
*
|
|
156
|
-
* We NEVER put arbitrary children
|
|
157
|
-
* inside UIText.
|
|
158
|
-
*/
|
|
159
|
-
const hasCustomChildren = children !== undefined && children !== null;
|
|
160
|
-
|
|
161
|
-
const accessibilityText =
|
|
162
|
-
accessibilityLabel ?? (typeof title === "string" ? title : undefined);
|
|
130
|
+
const hasChildren = children !== undefined && children !== null;
|
|
163
131
|
|
|
164
132
|
return (
|
|
165
133
|
<Pressable
|
|
@@ -171,34 +139,35 @@ const UIButtonComponent = ({
|
|
|
171
139
|
onPressIn={handlePressIn}
|
|
172
140
|
onPressOut={handlePressOut}
|
|
173
141
|
hitSlop={hitSlop}
|
|
174
|
-
pressRetentionOffset={pressRetentionOffset}
|
|
175
142
|
android_ripple={ripple}
|
|
176
|
-
accessibilityRole=
|
|
177
|
-
accessibilityLabel={
|
|
143
|
+
accessibilityRole="button"
|
|
144
|
+
accessibilityLabel={
|
|
145
|
+
accessibilityLabel || (typeof title === "string" ? title : undefined)
|
|
146
|
+
}
|
|
178
147
|
accessibilityHint={accessibilityHint}
|
|
179
148
|
accessibilityState={{
|
|
180
149
|
disabled: isDisabled,
|
|
181
|
-
busy:
|
|
150
|
+
busy: loading,
|
|
182
151
|
}}
|
|
183
152
|
style={({ pressed }) => [
|
|
184
153
|
styles.button,
|
|
185
154
|
|
|
186
155
|
{
|
|
187
|
-
minHeight:
|
|
156
|
+
minHeight: sizeStyle.height,
|
|
188
157
|
|
|
189
|
-
paddingHorizontal:
|
|
158
|
+
paddingHorizontal: sizeStyle.paddingHorizontal,
|
|
190
159
|
|
|
191
|
-
borderRadius:
|
|
160
|
+
borderRadius: sizeStyle.borderRadius,
|
|
192
161
|
|
|
193
|
-
backgroundColor:
|
|
162
|
+
backgroundColor: variantStyle.background,
|
|
194
163
|
|
|
195
|
-
borderColor:
|
|
164
|
+
borderColor: variantStyle.border,
|
|
196
165
|
|
|
197
|
-
borderWidth:
|
|
166
|
+
borderWidth: variantStyle.border ? 1 : 0,
|
|
198
167
|
|
|
199
168
|
width: fullWidth ? "100%" : undefined,
|
|
200
169
|
|
|
201
|
-
opacity: isDisabled ? 0.
|
|
170
|
+
opacity: isDisabled ? 0.5 : pressed ? activeOpacity : 1,
|
|
202
171
|
},
|
|
203
172
|
|
|
204
173
|
style,
|
|
@@ -209,157 +178,237 @@ const UIButtonComponent = ({
|
|
|
209
178
|
styles.content,
|
|
210
179
|
|
|
211
180
|
{
|
|
212
|
-
minHeight:
|
|
181
|
+
minHeight: sizeStyle.height - 2,
|
|
213
182
|
|
|
214
|
-
gap:
|
|
183
|
+
gap: sizeStyle.gap,
|
|
215
184
|
},
|
|
216
185
|
|
|
217
186
|
contentStyle,
|
|
218
187
|
]}
|
|
219
188
|
>
|
|
220
189
|
{loading ? (
|
|
221
|
-
<ActivityIndicator size="small" color={
|
|
222
|
-
) : (
|
|
223
|
-
leftIcon
|
|
224
|
-
)}
|
|
190
|
+
<ActivityIndicator size="small" color={variantStyle.text} />
|
|
191
|
+
) : leftIcon ? (
|
|
192
|
+
<View style={styles.iconContainer}>{leftIcon}</View>
|
|
193
|
+
) : null}
|
|
225
194
|
|
|
226
|
-
{
|
|
195
|
+
{hasChildren ? (
|
|
227
196
|
<View style={styles.children}>{children}</View>
|
|
228
197
|
) : title !== undefined && title !== null ? (
|
|
229
|
-
<
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
style={
|
|
233
|
-
numberOfLines={1}
|
|
198
|
+
<ButtonText
|
|
199
|
+
color={variantStyle.text}
|
|
200
|
+
sizeStyle={sizeStyle}
|
|
201
|
+
style={textStyle}
|
|
234
202
|
>
|
|
235
203
|
{title}
|
|
236
|
-
</
|
|
204
|
+
</ButtonText>
|
|
237
205
|
) : null}
|
|
238
206
|
|
|
239
207
|
{!loading && rightIcon ? (
|
|
240
|
-
<View style={styles.
|
|
208
|
+
<View style={styles.iconContainer}>{rightIcon}</View>
|
|
241
209
|
) : null}
|
|
242
210
|
</View>
|
|
243
211
|
</Pressable>
|
|
244
212
|
);
|
|
245
213
|
};
|
|
246
214
|
|
|
247
|
-
function
|
|
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
|
+
}
|
|
224
|
+
|
|
225
|
+
function ButtonTextNative({ children, color, sizeStyle, style }) {
|
|
226
|
+
const { theme } = useUITheme();
|
|
227
|
+
|
|
228
|
+
const { Text } = require("react-native");
|
|
229
|
+
|
|
230
|
+
return (
|
|
231
|
+
<Text
|
|
232
|
+
numberOfLines={1}
|
|
233
|
+
style={[
|
|
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) {
|
|
255
|
+
const primary = colors.primary || "#FF5A1F";
|
|
256
|
+
|
|
257
|
+
const primarySoft = colors.primarySoft || "#FFF0EA";
|
|
258
|
+
|
|
259
|
+
const primaryPressed = colors.primaryPressed || primary;
|
|
260
|
+
|
|
261
|
+
const success = colors.success || "#16A34A";
|
|
262
|
+
|
|
263
|
+
const danger = colors.danger || "#DC2626";
|
|
264
|
+
|
|
265
|
+
const surface = colors.surface || "#F5F5F5";
|
|
266
|
+
|
|
267
|
+
const border = colors.border || "#E5E5E5";
|
|
268
|
+
|
|
269
|
+
const borderStrong = colors.borderStrong || "#D4D4D4";
|
|
270
|
+
|
|
271
|
+
const text = colors.text || "#111111";
|
|
272
|
+
|
|
273
|
+
const onPrimary = colors.onPrimary || "#FFFFFF";
|
|
274
|
+
|
|
248
275
|
switch (variant) {
|
|
249
276
|
case BUTTON_VARIANTS.outline:
|
|
250
277
|
return {
|
|
251
|
-
background: colors.transparent,
|
|
278
|
+
background: colors.transparent || "transparent",
|
|
252
279
|
|
|
253
|
-
border:
|
|
280
|
+
border: primary,
|
|
254
281
|
|
|
255
|
-
text:
|
|
282
|
+
text: primary,
|
|
256
283
|
|
|
257
|
-
ripple:
|
|
284
|
+
ripple: primarySoft,
|
|
258
285
|
};
|
|
259
286
|
|
|
260
287
|
case BUTTON_VARIANTS.ghost:
|
|
261
288
|
return {
|
|
262
|
-
background: colors.transparent,
|
|
289
|
+
background: colors.transparent || "transparent",
|
|
263
290
|
|
|
264
291
|
border: null,
|
|
265
292
|
|
|
266
|
-
text:
|
|
293
|
+
text: primary,
|
|
267
294
|
|
|
268
|
-
ripple:
|
|
295
|
+
ripple: primarySoft,
|
|
269
296
|
};
|
|
270
297
|
|
|
271
298
|
case BUTTON_VARIANTS.soft:
|
|
272
299
|
return {
|
|
273
|
-
background:
|
|
300
|
+
background: primarySoft,
|
|
274
301
|
|
|
275
302
|
border: null,
|
|
276
303
|
|
|
277
|
-
text:
|
|
304
|
+
text: primary,
|
|
278
305
|
|
|
279
|
-
ripple:
|
|
306
|
+
ripple: primary,
|
|
280
307
|
};
|
|
281
308
|
|
|
282
309
|
case BUTTON_VARIANTS.danger:
|
|
283
310
|
return {
|
|
284
|
-
background:
|
|
311
|
+
background: danger,
|
|
285
312
|
|
|
286
|
-
border:
|
|
313
|
+
border: danger,
|
|
287
314
|
|
|
288
|
-
text:
|
|
315
|
+
text: onPrimary,
|
|
289
316
|
|
|
290
|
-
ripple:
|
|
317
|
+
ripple: danger,
|
|
291
318
|
};
|
|
292
319
|
|
|
293
320
|
case BUTTON_VARIANTS.success:
|
|
294
321
|
return {
|
|
295
|
-
background:
|
|
322
|
+
background: success,
|
|
296
323
|
|
|
297
|
-
border:
|
|
324
|
+
border: success,
|
|
298
325
|
|
|
299
|
-
text:
|
|
326
|
+
text: onPrimary,
|
|
300
327
|
|
|
301
|
-
ripple:
|
|
328
|
+
ripple: success,
|
|
302
329
|
};
|
|
303
330
|
|
|
304
331
|
case BUTTON_VARIANTS.solid:
|
|
305
332
|
default:
|
|
306
333
|
return {
|
|
307
|
-
background:
|
|
334
|
+
background: primary,
|
|
308
335
|
|
|
309
|
-
border:
|
|
336
|
+
border: primary,
|
|
310
337
|
|
|
311
|
-
text:
|
|
338
|
+
text: onPrimary,
|
|
312
339
|
|
|
313
|
-
ripple:
|
|
340
|
+
ripple: primaryPressed,
|
|
314
341
|
};
|
|
315
342
|
}
|
|
316
343
|
}
|
|
317
344
|
|
|
318
|
-
function
|
|
345
|
+
function resolveSize(size, theme) {
|
|
346
|
+
const spacing = theme.spacing;
|
|
347
|
+
|
|
348
|
+
const sizes = theme.sizes;
|
|
349
|
+
|
|
350
|
+
const radius = theme.radius;
|
|
351
|
+
|
|
319
352
|
switch (size) {
|
|
320
353
|
case BUTTON_SIZES.sm:
|
|
321
354
|
return {
|
|
322
|
-
height:
|
|
355
|
+
height: sizes.button.sm,
|
|
356
|
+
|
|
357
|
+
paddingHorizontal: spacing.md,
|
|
323
358
|
|
|
324
|
-
|
|
359
|
+
gap: spacing.xs,
|
|
325
360
|
|
|
326
|
-
|
|
361
|
+
borderRadius: radius.button,
|
|
327
362
|
|
|
328
|
-
|
|
363
|
+
fontSize: 13,
|
|
364
|
+
|
|
365
|
+
lineHeight: 18,
|
|
329
366
|
};
|
|
330
367
|
|
|
331
368
|
case BUTTON_SIZES.lg:
|
|
332
369
|
return {
|
|
333
|
-
height:
|
|
370
|
+
height: sizes.button.lg,
|
|
371
|
+
|
|
372
|
+
paddingHorizontal: spacing.xl,
|
|
334
373
|
|
|
335
|
-
|
|
374
|
+
gap: spacing.sm,
|
|
336
375
|
|
|
337
|
-
|
|
376
|
+
borderRadius: radius.button,
|
|
338
377
|
|
|
339
|
-
|
|
378
|
+
fontSize: 16,
|
|
379
|
+
|
|
380
|
+
lineHeight: 22,
|
|
340
381
|
};
|
|
341
382
|
|
|
342
383
|
case BUTTON_SIZES.xl:
|
|
343
384
|
return {
|
|
344
|
-
height:
|
|
385
|
+
height: sizes.button.xl,
|
|
386
|
+
|
|
387
|
+
paddingHorizontal: spacing.xl2,
|
|
345
388
|
|
|
346
|
-
|
|
389
|
+
gap: spacing.sm,
|
|
347
390
|
|
|
348
|
-
|
|
391
|
+
borderRadius: radius.button,
|
|
349
392
|
|
|
350
|
-
|
|
393
|
+
fontSize: 17,
|
|
394
|
+
|
|
395
|
+
lineHeight: 24,
|
|
351
396
|
};
|
|
352
397
|
|
|
353
398
|
case BUTTON_SIZES.md:
|
|
354
399
|
default:
|
|
355
400
|
return {
|
|
356
|
-
height:
|
|
401
|
+
height: sizes.button.md,
|
|
402
|
+
|
|
403
|
+
paddingHorizontal: spacing.lg,
|
|
404
|
+
|
|
405
|
+
gap: spacing.sm,
|
|
357
406
|
|
|
358
|
-
|
|
407
|
+
borderRadius: radius.button,
|
|
359
408
|
|
|
360
|
-
|
|
409
|
+
fontSize: 14,
|
|
361
410
|
|
|
362
|
-
|
|
411
|
+
lineHeight: 20,
|
|
363
412
|
};
|
|
364
413
|
}
|
|
365
414
|
}
|
|
@@ -386,16 +435,15 @@ const styles = StyleSheet.create({
|
|
|
386
435
|
justifyContent: "center",
|
|
387
436
|
},
|
|
388
437
|
|
|
389
|
-
|
|
390
|
-
flexShrink: 1,
|
|
391
|
-
textAlign: "center",
|
|
392
|
-
},
|
|
393
|
-
|
|
394
|
-
iconRight: {
|
|
438
|
+
iconContainer: {
|
|
395
439
|
alignItems: "center",
|
|
396
440
|
justifyContent: "center",
|
|
397
441
|
flexShrink: 0,
|
|
398
442
|
},
|
|
443
|
+
|
|
444
|
+
textWrapper: {
|
|
445
|
+
flexShrink: 1,
|
|
446
|
+
},
|
|
399
447
|
});
|
|
400
448
|
|
|
401
449
|
export const UIButton = memo(UIButtonComponent);
|