@xsolla/xui-tab-bar-native 0.64.0-pr56.1768348754

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/index.mjs ADDED
@@ -0,0 +1,643 @@
1
+ // ../primitives-native/src/Box.tsx
2
+ import {
3
+ View,
4
+ Pressable,
5
+ Image
6
+ } from "react-native";
7
+ import { jsx } from "react/jsx-runtime";
8
+ var Box = ({
9
+ children,
10
+ onPress,
11
+ onLayout,
12
+ onMoveShouldSetResponder,
13
+ onResponderGrant,
14
+ onResponderMove,
15
+ onResponderRelease,
16
+ onResponderTerminate,
17
+ backgroundColor,
18
+ borderColor,
19
+ borderWidth,
20
+ borderBottomWidth,
21
+ borderBottomColor,
22
+ borderTopWidth,
23
+ borderTopColor,
24
+ borderLeftWidth,
25
+ borderLeftColor,
26
+ borderRightWidth,
27
+ borderRightColor,
28
+ borderRadius,
29
+ borderStyle,
30
+ height,
31
+ padding,
32
+ paddingHorizontal,
33
+ paddingVertical,
34
+ margin,
35
+ marginTop,
36
+ marginBottom,
37
+ marginLeft,
38
+ marginRight,
39
+ flexDirection,
40
+ alignItems,
41
+ justifyContent,
42
+ position,
43
+ top,
44
+ bottom,
45
+ left,
46
+ right,
47
+ width,
48
+ flex,
49
+ overflow,
50
+ zIndex,
51
+ hoverStyle,
52
+ pressStyle,
53
+ style,
54
+ "data-testid": dataTestId,
55
+ testID,
56
+ as,
57
+ src,
58
+ alt,
59
+ ...rest
60
+ }) => {
61
+ const getContainerStyle = (pressed) => ({
62
+ backgroundColor: pressed && pressStyle?.backgroundColor ? pressStyle.backgroundColor : backgroundColor,
63
+ borderColor,
64
+ borderWidth,
65
+ borderBottomWidth,
66
+ borderBottomColor,
67
+ borderTopWidth,
68
+ borderTopColor,
69
+ borderLeftWidth,
70
+ borderLeftColor,
71
+ borderRightWidth,
72
+ borderRightColor,
73
+ borderRadius,
74
+ borderStyle,
75
+ overflow,
76
+ zIndex,
77
+ height,
78
+ width,
79
+ padding,
80
+ paddingHorizontal,
81
+ paddingVertical,
82
+ margin,
83
+ marginTop,
84
+ marginBottom,
85
+ marginLeft,
86
+ marginRight,
87
+ flexDirection,
88
+ alignItems,
89
+ justifyContent,
90
+ position,
91
+ top,
92
+ bottom,
93
+ left,
94
+ right,
95
+ flex,
96
+ ...style
97
+ });
98
+ const finalTestID = dataTestId || testID;
99
+ const {
100
+ role,
101
+ tabIndex,
102
+ onKeyDown,
103
+ onKeyUp,
104
+ "aria-label": _ariaLabel,
105
+ "aria-labelledby": _ariaLabelledBy,
106
+ "aria-current": _ariaCurrent,
107
+ "aria-disabled": _ariaDisabled,
108
+ "aria-live": _ariaLive,
109
+ className,
110
+ "data-testid": _dataTestId,
111
+ ...nativeRest
112
+ } = rest;
113
+ if (as === "img" && src) {
114
+ const imageStyle = {
115
+ width,
116
+ height,
117
+ borderRadius,
118
+ position,
119
+ top,
120
+ bottom,
121
+ left,
122
+ right,
123
+ ...style
124
+ };
125
+ return /* @__PURE__ */ jsx(
126
+ Image,
127
+ {
128
+ source: { uri: src },
129
+ style: imageStyle,
130
+ testID: finalTestID,
131
+ resizeMode: "cover",
132
+ ...nativeRest
133
+ }
134
+ );
135
+ }
136
+ if (onPress) {
137
+ return /* @__PURE__ */ jsx(
138
+ Pressable,
139
+ {
140
+ onPress,
141
+ onLayout,
142
+ onMoveShouldSetResponder,
143
+ onResponderGrant,
144
+ onResponderMove,
145
+ onResponderRelease,
146
+ onResponderTerminate,
147
+ style: ({ pressed }) => getContainerStyle(pressed),
148
+ testID: finalTestID,
149
+ ...nativeRest,
150
+ children
151
+ }
152
+ );
153
+ }
154
+ return /* @__PURE__ */ jsx(
155
+ View,
156
+ {
157
+ style: getContainerStyle(),
158
+ testID: finalTestID,
159
+ onLayout,
160
+ onMoveShouldSetResponder,
161
+ onResponderGrant,
162
+ onResponderMove,
163
+ onResponderRelease,
164
+ onResponderTerminate,
165
+ ...nativeRest,
166
+ children
167
+ }
168
+ );
169
+ };
170
+
171
+ // ../primitives-native/src/Text.tsx
172
+ import { Text as RNText } from "react-native";
173
+ import { jsx as jsx2 } from "react/jsx-runtime";
174
+ var roleMap = {
175
+ alert: "alert",
176
+ heading: "header",
177
+ button: "button",
178
+ link: "link",
179
+ text: "text"
180
+ };
181
+ var Text = ({
182
+ children,
183
+ color,
184
+ fontSize,
185
+ fontWeight,
186
+ fontFamily,
187
+ id,
188
+ role,
189
+ ...props
190
+ }) => {
191
+ let resolvedFontFamily = fontFamily ? fontFamily.split(",")[0].replace(/['"]/g, "").trim() : void 0;
192
+ if (resolvedFontFamily === "Pilat Wide Bold") {
193
+ resolvedFontFamily = void 0;
194
+ }
195
+ const style = {
196
+ color,
197
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
198
+ fontWeight,
199
+ fontFamily: resolvedFontFamily,
200
+ textDecorationLine: props.textDecoration
201
+ };
202
+ const accessibilityRole = role ? roleMap[role] : void 0;
203
+ return /* @__PURE__ */ jsx2(RNText, { style, testID: id, accessibilityRole, children });
204
+ };
205
+
206
+ // ../primitives-native/src/Spinner.tsx
207
+ import { ActivityIndicator, View as View2 } from "react-native";
208
+ import { jsx as jsx3 } from "react/jsx-runtime";
209
+ var Spinner = ({
210
+ color,
211
+ size,
212
+ role,
213
+ "aria-label": ariaLabel,
214
+ "aria-live": ariaLive,
215
+ "aria-describedby": ariaDescribedBy,
216
+ testID
217
+ }) => {
218
+ return /* @__PURE__ */ jsx3(
219
+ View2,
220
+ {
221
+ accessible: true,
222
+ accessibilityRole: role === "status" ? "none" : void 0,
223
+ accessibilityLabel: ariaLabel,
224
+ accessibilityLiveRegion: ariaLive === "polite" ? "polite" : ariaLive === "assertive" ? "assertive" : "none",
225
+ testID,
226
+ children: /* @__PURE__ */ jsx3(
227
+ ActivityIndicator,
228
+ {
229
+ color,
230
+ size: typeof size === "number" ? size : "small"
231
+ }
232
+ )
233
+ }
234
+ );
235
+ };
236
+ Spinner.displayName = "Spinner";
237
+
238
+ // ../primitives-native/src/Icon.tsx
239
+ import React from "react";
240
+ import { View as View3 } from "react-native";
241
+ import { jsx as jsx4 } from "react/jsx-runtime";
242
+ var Icon = ({ children, color, size }) => {
243
+ const style = {
244
+ width: typeof size === "number" ? size : void 0,
245
+ height: typeof size === "number" ? size : void 0,
246
+ alignItems: "center",
247
+ justifyContent: "center"
248
+ };
249
+ const childrenWithProps = React.Children.map(children, (child) => {
250
+ if (React.isValidElement(child)) {
251
+ return React.cloneElement(child, {
252
+ color: child.props.color || color,
253
+ // Also pass size if child seems to be an icon that needs it
254
+ size: child.props.size || size
255
+ });
256
+ }
257
+ return child;
258
+ });
259
+ return /* @__PURE__ */ jsx4(View3, { style, children: childrenWithProps });
260
+ };
261
+
262
+ // ../primitives-native/src/Divider.tsx
263
+ import { View as View4 } from "react-native";
264
+ import { jsx as jsx5 } from "react/jsx-runtime";
265
+
266
+ // ../primitives-native/src/Input.tsx
267
+ import { forwardRef } from "react";
268
+ import { TextInput as RNTextInput } from "react-native";
269
+ import { jsx as jsx6 } from "react/jsx-runtime";
270
+ var keyboardTypeMap = {
271
+ text: "default",
272
+ number: "numeric",
273
+ email: "email-address",
274
+ tel: "phone-pad",
275
+ url: "url",
276
+ decimal: "decimal-pad"
277
+ };
278
+ var inputModeToKeyboardType = {
279
+ none: "default",
280
+ text: "default",
281
+ decimal: "decimal-pad",
282
+ numeric: "number-pad",
283
+ tel: "phone-pad",
284
+ search: "default",
285
+ email: "email-address",
286
+ url: "url"
287
+ };
288
+ var autoCompleteToTextContentType = {
289
+ "one-time-code": "oneTimeCode",
290
+ email: "emailAddress",
291
+ username: "username",
292
+ password: "password",
293
+ "new-password": "newPassword",
294
+ tel: "telephoneNumber",
295
+ "postal-code": "postalCode",
296
+ name: "name"
297
+ };
298
+ var InputPrimitive = forwardRef(
299
+ ({
300
+ value,
301
+ placeholder,
302
+ onChange,
303
+ onChangeText,
304
+ onFocus,
305
+ onBlur,
306
+ onKeyDown,
307
+ disabled,
308
+ secureTextEntry,
309
+ style,
310
+ color,
311
+ fontSize,
312
+ placeholderTextColor,
313
+ maxLength,
314
+ name,
315
+ type,
316
+ inputMode,
317
+ autoComplete,
318
+ id,
319
+ "aria-invalid": ariaInvalid,
320
+ "aria-describedby": ariaDescribedBy,
321
+ "aria-labelledby": ariaLabelledBy,
322
+ "aria-label": ariaLabel,
323
+ "aria-disabled": ariaDisabled,
324
+ "data-testid": dataTestId
325
+ }, ref) => {
326
+ const handleChangeText = (text) => {
327
+ onChangeText?.(text);
328
+ if (onChange) {
329
+ const syntheticEvent = {
330
+ target: { value: text },
331
+ currentTarget: { value: text },
332
+ type: "change",
333
+ nativeEvent: { text },
334
+ preventDefault: () => {
335
+ },
336
+ stopPropagation: () => {
337
+ },
338
+ isTrusted: false
339
+ };
340
+ onChange(syntheticEvent);
341
+ }
342
+ };
343
+ const keyboardType = inputMode ? inputModeToKeyboardType[inputMode] || "default" : type ? keyboardTypeMap[type] || "default" : "default";
344
+ const textContentType = autoComplete ? autoCompleteToTextContentType[autoComplete] : void 0;
345
+ return /* @__PURE__ */ jsx6(
346
+ RNTextInput,
347
+ {
348
+ ref,
349
+ value,
350
+ placeholder,
351
+ onChangeText: handleChangeText,
352
+ onFocus,
353
+ onBlur,
354
+ onKeyPress: (e) => {
355
+ if (onKeyDown) {
356
+ onKeyDown({
357
+ key: e.nativeEvent.key,
358
+ preventDefault: () => {
359
+ }
360
+ });
361
+ }
362
+ },
363
+ editable: !disabled,
364
+ secureTextEntry: secureTextEntry || type === "password",
365
+ keyboardType,
366
+ textContentType,
367
+ style: [
368
+ {
369
+ color,
370
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
371
+ flex: 1,
372
+ padding: 0,
373
+ textAlign: style?.textAlign || "left"
374
+ },
375
+ style
376
+ ],
377
+ placeholderTextColor,
378
+ maxLength,
379
+ testID: dataTestId || id,
380
+ accessibilityLabel: ariaLabel,
381
+ accessibilityHint: ariaDescribedBy,
382
+ accessibilityState: {
383
+ disabled: disabled || ariaDisabled
384
+ },
385
+ accessible: true
386
+ }
387
+ );
388
+ }
389
+ );
390
+ InputPrimitive.displayName = "InputPrimitive";
391
+
392
+ // ../primitives-native/src/TextArea.tsx
393
+ import { forwardRef as forwardRef2 } from "react";
394
+ import { TextInput as RNTextInput2 } from "react-native";
395
+ import { jsx as jsx7 } from "react/jsx-runtime";
396
+ var TextAreaPrimitive = forwardRef2(
397
+ ({
398
+ value,
399
+ placeholder,
400
+ onChange,
401
+ onChangeText,
402
+ onFocus,
403
+ onBlur,
404
+ onKeyDown,
405
+ disabled,
406
+ style,
407
+ color,
408
+ fontSize,
409
+ placeholderTextColor,
410
+ maxLength,
411
+ rows,
412
+ id,
413
+ "aria-invalid": ariaInvalid,
414
+ "aria-describedby": ariaDescribedBy,
415
+ "aria-labelledby": ariaLabelledBy,
416
+ "aria-label": ariaLabel,
417
+ "aria-disabled": ariaDisabled,
418
+ "data-testid": dataTestId
419
+ }, ref) => {
420
+ const handleChangeText = (text) => {
421
+ onChangeText?.(text);
422
+ if (onChange) {
423
+ const syntheticEvent = {
424
+ target: { value: text },
425
+ currentTarget: { value: text },
426
+ type: "change",
427
+ nativeEvent: { text },
428
+ preventDefault: () => {
429
+ },
430
+ stopPropagation: () => {
431
+ },
432
+ isTrusted: false
433
+ };
434
+ onChange(syntheticEvent);
435
+ }
436
+ };
437
+ return /* @__PURE__ */ jsx7(
438
+ RNTextInput2,
439
+ {
440
+ ref,
441
+ value,
442
+ placeholder,
443
+ onChangeText: handleChangeText,
444
+ onFocus,
445
+ onBlur,
446
+ onKeyPress: (e) => {
447
+ if (onKeyDown) {
448
+ onKeyDown({
449
+ key: e.nativeEvent.key,
450
+ preventDefault: () => {
451
+ }
452
+ });
453
+ }
454
+ },
455
+ editable: !disabled,
456
+ multiline: true,
457
+ numberOfLines: rows || 4,
458
+ style: [
459
+ {
460
+ color,
461
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
462
+ flex: 1,
463
+ padding: 0,
464
+ textAlignVertical: "top",
465
+ textAlign: style?.textAlign || "left"
466
+ },
467
+ style
468
+ ],
469
+ placeholderTextColor,
470
+ maxLength,
471
+ testID: dataTestId || id,
472
+ accessibilityLabel: ariaLabel,
473
+ accessibilityHint: ariaDescribedBy,
474
+ accessibilityState: {
475
+ disabled: disabled || ariaDisabled
476
+ },
477
+ accessible: true
478
+ }
479
+ );
480
+ }
481
+ );
482
+ TextAreaPrimitive.displayName = "TextAreaPrimitive";
483
+
484
+ // src/TabBar.tsx
485
+ import { useDesignSystem as useDesignSystem2 } from "@xsolla/xui-core";
486
+
487
+ // src/TabBarItem.tsx
488
+ import { cloneElement, isValidElement } from "react";
489
+ import { useDesignSystem } from "@xsolla/xui-core";
490
+ import { Badge } from "@xsolla/xui-badge";
491
+ import { jsx as jsx8, jsxs } from "react/jsx-runtime";
492
+ var TabBarItem = ({
493
+ label,
494
+ icon,
495
+ badge,
496
+ focused,
497
+ onPress,
498
+ onLongPress,
499
+ labelPosition,
500
+ accessibilityLabel,
501
+ testID
502
+ }) => {
503
+ const { theme } = useDesignSystem();
504
+ const color = focused ? theme.colors.content.brand.primary : theme.colors.content.primary;
505
+ const renderIcon = () => {
506
+ if (!icon) return null;
507
+ return /* @__PURE__ */ jsxs(Box, { position: "relative", alignItems: "center", justifyContent: "center", children: [
508
+ /* @__PURE__ */ jsx8(Icon, { size: 24, color, children: isValidElement(icon) ? cloneElement(icon, {
509
+ size: 24,
510
+ color,
511
+ stroke: color
512
+ }) : icon }),
513
+ badge !== void 0 && badge !== null && /* @__PURE__ */ jsx8(
514
+ Box,
515
+ {
516
+ position: "absolute",
517
+ top: -5,
518
+ right: -10,
519
+ zIndex: 1,
520
+ children: /* @__PURE__ */ jsx8(Badge, { size: "s", children: badge })
521
+ }
522
+ )
523
+ ] });
524
+ };
525
+ const renderLabel = () => {
526
+ if (typeof label === "string") {
527
+ return /* @__PURE__ */ jsx8(
528
+ Text,
529
+ {
530
+ color,
531
+ fontSize: 12,
532
+ fontWeight: focused ? "600" : "400",
533
+ numberOfLines: 1,
534
+ children: label
535
+ }
536
+ );
537
+ }
538
+ return label;
539
+ };
540
+ return /* @__PURE__ */ jsxs(
541
+ Box,
542
+ {
543
+ flex: 1,
544
+ alignItems: "center",
545
+ justifyContent: "center",
546
+ paddingVertical: 8,
547
+ cursor: "pointer",
548
+ flexDirection: labelPosition === "beside-icon" ? "row" : "column",
549
+ gap: labelPosition === "beside-icon" ? 8 : 4,
550
+ onPress,
551
+ onLongPress,
552
+ accessibilityLabel,
553
+ testID,
554
+ role: "button",
555
+ hoverStyle: {
556
+ backgroundColor: theme.colors.overlay.mono
557
+ },
558
+ children: [
559
+ renderIcon(),
560
+ renderLabel()
561
+ ]
562
+ }
563
+ );
564
+ };
565
+ TabBarItem.displayName = "TabBarItem";
566
+
567
+ // src/TabBar.tsx
568
+ import { jsx as jsx9 } from "react/jsx-runtime";
569
+ var TabBar = ({
570
+ state,
571
+ descriptors,
572
+ navigation,
573
+ labelPosition = "below-icon",
574
+ backgroundColor,
575
+ testID
576
+ }) => {
577
+ const { theme } = useDesignSystem2();
578
+ return /* @__PURE__ */ jsx9(
579
+ Box,
580
+ {
581
+ flexDirection: "row",
582
+ backgroundColor: backgroundColor || theme.colors.background.primary,
583
+ borderTopWidth: 1,
584
+ borderTopColor: theme.colors.border.secondary,
585
+ borderStyle: "solid",
586
+ height: 60,
587
+ width: "100%",
588
+ testID: testID || "tab-bar-container",
589
+ children: state.routes.map((route, index) => {
590
+ const { options } = descriptors[route.key];
591
+ const label = options.tabBarShowLabel === false ? void 0 : options.tabBarLabel !== void 0 ? options.tabBarLabel : options.title !== void 0 ? options.title : route.name;
592
+ const isFocused = state.index === index;
593
+ const onPress = () => {
594
+ const event = navigation.emit({
595
+ type: "tabPress",
596
+ target: route.key,
597
+ canPreventDefault: true
598
+ });
599
+ if (!isFocused && !event.defaultPrevented) {
600
+ navigation.navigate(route.name, route.params);
601
+ }
602
+ };
603
+ const onLongPress = () => {
604
+ navigation.emit({
605
+ type: "tabLongPress",
606
+ target: route.key
607
+ });
608
+ };
609
+ const icon = options.tabBarIcon ? options.tabBarIcon({
610
+ focused: isFocused,
611
+ color: isFocused ? theme.colors.content.brand.primary : theme.colors.content.primary,
612
+ size: 24
613
+ }) : void 0;
614
+ const badge = options.tabBarBadge;
615
+ return /* @__PURE__ */ jsx9(
616
+ TabBarItem,
617
+ {
618
+ label: typeof label === "function" ? label({
619
+ focused: isFocused,
620
+ color: isFocused ? theme.colors.content.brand.primary : theme.colors.content.primary,
621
+ position: labelPosition
622
+ }) : label,
623
+ icon,
624
+ badge,
625
+ focused: isFocused,
626
+ onPress,
627
+ onLongPress,
628
+ labelPosition,
629
+ accessibilityLabel: options.tabBarAccessibilityLabel,
630
+ testID: options.tabBarTestID
631
+ },
632
+ route.key
633
+ );
634
+ })
635
+ }
636
+ );
637
+ };
638
+ TabBar.displayName = "TabBar";
639
+ export {
640
+ TabBar,
641
+ TabBarItem
642
+ };
643
+ //# sourceMappingURL=index.mjs.map