@xsolla/xui-checkbox 0.64.0-pr56.1768440195

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.
@@ -0,0 +1,727 @@
1
+ // src/Checkbox.tsx
2
+ import {
3
+ forwardRef as forwardRef3,
4
+ useRef,
5
+ useState,
6
+ useImperativeHandle
7
+ } from "react";
8
+
9
+ // ../primitives-native/src/Box.tsx
10
+ import {
11
+ View,
12
+ Pressable,
13
+ Image
14
+ } from "react-native";
15
+ import { jsx } from "react/jsx-runtime";
16
+ var Box = ({
17
+ children,
18
+ onPress,
19
+ onLayout,
20
+ onMoveShouldSetResponder,
21
+ onResponderGrant,
22
+ onResponderMove,
23
+ onResponderRelease,
24
+ onResponderTerminate,
25
+ backgroundColor,
26
+ borderColor,
27
+ borderWidth,
28
+ borderBottomWidth,
29
+ borderBottomColor,
30
+ borderTopWidth,
31
+ borderTopColor,
32
+ borderLeftWidth,
33
+ borderLeftColor,
34
+ borderRightWidth,
35
+ borderRightColor,
36
+ borderRadius,
37
+ borderStyle,
38
+ height,
39
+ padding,
40
+ paddingHorizontal,
41
+ paddingVertical,
42
+ margin,
43
+ marginTop,
44
+ marginBottom,
45
+ marginLeft,
46
+ marginRight,
47
+ flexDirection,
48
+ alignItems,
49
+ justifyContent,
50
+ position,
51
+ top,
52
+ bottom,
53
+ left,
54
+ right,
55
+ width,
56
+ flex,
57
+ overflow,
58
+ zIndex,
59
+ hoverStyle,
60
+ pressStyle,
61
+ style,
62
+ "data-testid": dataTestId,
63
+ testID,
64
+ as,
65
+ src,
66
+ alt,
67
+ ...rest
68
+ }) => {
69
+ const getContainerStyle = (pressed) => ({
70
+ backgroundColor: pressed && pressStyle?.backgroundColor ? pressStyle.backgroundColor : backgroundColor,
71
+ borderColor,
72
+ borderWidth,
73
+ borderBottomWidth,
74
+ borderBottomColor,
75
+ borderTopWidth,
76
+ borderTopColor,
77
+ borderLeftWidth,
78
+ borderLeftColor,
79
+ borderRightWidth,
80
+ borderRightColor,
81
+ borderRadius,
82
+ borderStyle,
83
+ overflow,
84
+ zIndex,
85
+ height,
86
+ width,
87
+ padding,
88
+ paddingHorizontal,
89
+ paddingVertical,
90
+ margin,
91
+ marginTop,
92
+ marginBottom,
93
+ marginLeft,
94
+ marginRight,
95
+ flexDirection,
96
+ alignItems,
97
+ justifyContent,
98
+ position,
99
+ top,
100
+ bottom,
101
+ left,
102
+ right,
103
+ flex,
104
+ ...style
105
+ });
106
+ const finalTestID = dataTestId || testID;
107
+ const {
108
+ role,
109
+ tabIndex,
110
+ onKeyDown,
111
+ onKeyUp,
112
+ "aria-label": _ariaLabel,
113
+ "aria-labelledby": _ariaLabelledBy,
114
+ "aria-current": _ariaCurrent,
115
+ "aria-disabled": _ariaDisabled,
116
+ "aria-live": _ariaLive,
117
+ className,
118
+ "data-testid": _dataTestId,
119
+ ...nativeRest
120
+ } = rest;
121
+ if (as === "img" && src) {
122
+ const imageStyle = {
123
+ width,
124
+ height,
125
+ borderRadius,
126
+ position,
127
+ top,
128
+ bottom,
129
+ left,
130
+ right,
131
+ ...style
132
+ };
133
+ return /* @__PURE__ */ jsx(
134
+ Image,
135
+ {
136
+ source: { uri: src },
137
+ style: imageStyle,
138
+ testID: finalTestID,
139
+ resizeMode: "cover",
140
+ ...nativeRest
141
+ }
142
+ );
143
+ }
144
+ if (onPress) {
145
+ return /* @__PURE__ */ jsx(
146
+ Pressable,
147
+ {
148
+ onPress,
149
+ onLayout,
150
+ onMoveShouldSetResponder,
151
+ onResponderGrant,
152
+ onResponderMove,
153
+ onResponderRelease,
154
+ onResponderTerminate,
155
+ style: ({ pressed }) => getContainerStyle(pressed),
156
+ testID: finalTestID,
157
+ ...nativeRest,
158
+ children
159
+ }
160
+ );
161
+ }
162
+ return /* @__PURE__ */ jsx(
163
+ View,
164
+ {
165
+ style: getContainerStyle(),
166
+ testID: finalTestID,
167
+ onLayout,
168
+ onMoveShouldSetResponder,
169
+ onResponderGrant,
170
+ onResponderMove,
171
+ onResponderRelease,
172
+ onResponderTerminate,
173
+ ...nativeRest,
174
+ children
175
+ }
176
+ );
177
+ };
178
+
179
+ // ../primitives-native/src/Text.tsx
180
+ import { Text as RNText } from "react-native";
181
+ import { jsx as jsx2 } from "react/jsx-runtime";
182
+ var roleMap = {
183
+ alert: "alert",
184
+ heading: "header",
185
+ button: "button",
186
+ link: "link",
187
+ text: "text"
188
+ };
189
+ var Text = ({
190
+ children,
191
+ color,
192
+ fontSize,
193
+ fontWeight,
194
+ fontFamily,
195
+ id,
196
+ role,
197
+ ...props
198
+ }) => {
199
+ let resolvedFontFamily = fontFamily ? fontFamily.split(",")[0].replace(/['"]/g, "").trim() : void 0;
200
+ if (resolvedFontFamily === "Pilat Wide Bold") {
201
+ resolvedFontFamily = void 0;
202
+ }
203
+ const style = {
204
+ color,
205
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
206
+ fontWeight,
207
+ fontFamily: resolvedFontFamily,
208
+ textDecorationLine: props.textDecoration
209
+ };
210
+ const accessibilityRole = role ? roleMap[role] : void 0;
211
+ return /* @__PURE__ */ jsx2(RNText, { style, testID: id, accessibilityRole, children });
212
+ };
213
+
214
+ // ../primitives-native/src/Spinner.tsx
215
+ import { ActivityIndicator, View as View2 } from "react-native";
216
+ import { jsx as jsx3 } from "react/jsx-runtime";
217
+ var Spinner = ({
218
+ color,
219
+ size,
220
+ role,
221
+ "aria-label": ariaLabel,
222
+ "aria-live": ariaLive,
223
+ "aria-describedby": ariaDescribedBy,
224
+ testID
225
+ }) => {
226
+ return /* @__PURE__ */ jsx3(
227
+ View2,
228
+ {
229
+ accessible: true,
230
+ accessibilityRole: role === "status" ? "none" : void 0,
231
+ accessibilityLabel: ariaLabel,
232
+ accessibilityLiveRegion: ariaLive === "polite" ? "polite" : ariaLive === "assertive" ? "assertive" : "none",
233
+ testID,
234
+ children: /* @__PURE__ */ jsx3(
235
+ ActivityIndicator,
236
+ {
237
+ color,
238
+ size: typeof size === "number" ? size : "small"
239
+ }
240
+ )
241
+ }
242
+ );
243
+ };
244
+ Spinner.displayName = "Spinner";
245
+
246
+ // ../primitives-native/src/Icon.tsx
247
+ import React from "react";
248
+ import { View as View3 } from "react-native";
249
+ import { jsx as jsx4 } from "react/jsx-runtime";
250
+
251
+ // ../primitives-native/src/Divider.tsx
252
+ import { View as View4 } from "react-native";
253
+ import { jsx as jsx5 } from "react/jsx-runtime";
254
+
255
+ // ../primitives-native/src/Input.tsx
256
+ import { forwardRef } from "react";
257
+ import { TextInput as RNTextInput } from "react-native";
258
+ import { jsx as jsx6 } from "react/jsx-runtime";
259
+ var keyboardTypeMap = {
260
+ text: "default",
261
+ number: "numeric",
262
+ email: "email-address",
263
+ tel: "phone-pad",
264
+ url: "url",
265
+ decimal: "decimal-pad"
266
+ };
267
+ var inputModeToKeyboardType = {
268
+ none: "default",
269
+ text: "default",
270
+ decimal: "decimal-pad",
271
+ numeric: "number-pad",
272
+ tel: "phone-pad",
273
+ search: "default",
274
+ email: "email-address",
275
+ url: "url"
276
+ };
277
+ var autoCompleteToTextContentType = {
278
+ "one-time-code": "oneTimeCode",
279
+ email: "emailAddress",
280
+ username: "username",
281
+ password: "password",
282
+ "new-password": "newPassword",
283
+ tel: "telephoneNumber",
284
+ "postal-code": "postalCode",
285
+ name: "name"
286
+ };
287
+ var InputPrimitive = forwardRef(
288
+ ({
289
+ value,
290
+ placeholder,
291
+ onChange,
292
+ onChangeText,
293
+ onFocus,
294
+ onBlur,
295
+ onKeyDown,
296
+ disabled,
297
+ secureTextEntry,
298
+ style,
299
+ color,
300
+ fontSize,
301
+ placeholderTextColor,
302
+ maxLength,
303
+ name,
304
+ type,
305
+ inputMode,
306
+ autoComplete,
307
+ id,
308
+ "aria-invalid": ariaInvalid,
309
+ "aria-describedby": ariaDescribedBy,
310
+ "aria-labelledby": ariaLabelledBy,
311
+ "aria-label": ariaLabel,
312
+ "aria-disabled": ariaDisabled,
313
+ "data-testid": dataTestId
314
+ }, ref) => {
315
+ const handleChangeText = (text) => {
316
+ onChangeText?.(text);
317
+ if (onChange) {
318
+ const syntheticEvent = {
319
+ target: { value: text },
320
+ currentTarget: { value: text },
321
+ type: "change",
322
+ nativeEvent: { text },
323
+ preventDefault: () => {
324
+ },
325
+ stopPropagation: () => {
326
+ },
327
+ isTrusted: false
328
+ };
329
+ onChange(syntheticEvent);
330
+ }
331
+ };
332
+ const keyboardType = inputMode ? inputModeToKeyboardType[inputMode] || "default" : type ? keyboardTypeMap[type] || "default" : "default";
333
+ const textContentType = autoComplete ? autoCompleteToTextContentType[autoComplete] : void 0;
334
+ return /* @__PURE__ */ jsx6(
335
+ RNTextInput,
336
+ {
337
+ ref,
338
+ value,
339
+ placeholder,
340
+ onChangeText: handleChangeText,
341
+ onFocus,
342
+ onBlur,
343
+ onKeyPress: (e) => {
344
+ if (onKeyDown) {
345
+ onKeyDown({
346
+ key: e.nativeEvent.key,
347
+ preventDefault: () => {
348
+ }
349
+ });
350
+ }
351
+ },
352
+ editable: !disabled,
353
+ secureTextEntry: secureTextEntry || type === "password",
354
+ keyboardType,
355
+ textContentType,
356
+ style: [
357
+ {
358
+ color,
359
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
360
+ flex: 1,
361
+ padding: 0,
362
+ textAlign: style?.textAlign || "left"
363
+ },
364
+ style
365
+ ],
366
+ placeholderTextColor,
367
+ maxLength,
368
+ testID: dataTestId || id,
369
+ accessibilityLabel: ariaLabel,
370
+ accessibilityHint: ariaDescribedBy,
371
+ accessibilityState: {
372
+ disabled: disabled || ariaDisabled
373
+ },
374
+ accessible: true
375
+ }
376
+ );
377
+ }
378
+ );
379
+ InputPrimitive.displayName = "InputPrimitive";
380
+
381
+ // ../primitives-native/src/TextArea.tsx
382
+ import { forwardRef as forwardRef2 } from "react";
383
+ import { TextInput as RNTextInput2 } from "react-native";
384
+ import { jsx as jsx7 } from "react/jsx-runtime";
385
+ var TextAreaPrimitive = forwardRef2(
386
+ ({
387
+ value,
388
+ placeholder,
389
+ onChange,
390
+ onChangeText,
391
+ onFocus,
392
+ onBlur,
393
+ onKeyDown,
394
+ disabled,
395
+ style,
396
+ color,
397
+ fontSize,
398
+ placeholderTextColor,
399
+ maxLength,
400
+ rows,
401
+ id,
402
+ "aria-invalid": ariaInvalid,
403
+ "aria-describedby": ariaDescribedBy,
404
+ "aria-labelledby": ariaLabelledBy,
405
+ "aria-label": ariaLabel,
406
+ "aria-disabled": ariaDisabled,
407
+ "data-testid": dataTestId
408
+ }, ref) => {
409
+ const handleChangeText = (text) => {
410
+ onChangeText?.(text);
411
+ if (onChange) {
412
+ const syntheticEvent = {
413
+ target: { value: text },
414
+ currentTarget: { value: text },
415
+ type: "change",
416
+ nativeEvent: { text },
417
+ preventDefault: () => {
418
+ },
419
+ stopPropagation: () => {
420
+ },
421
+ isTrusted: false
422
+ };
423
+ onChange(syntheticEvent);
424
+ }
425
+ };
426
+ return /* @__PURE__ */ jsx7(
427
+ RNTextInput2,
428
+ {
429
+ ref,
430
+ value,
431
+ placeholder,
432
+ onChangeText: handleChangeText,
433
+ onFocus,
434
+ onBlur,
435
+ onKeyPress: (e) => {
436
+ if (onKeyDown) {
437
+ onKeyDown({
438
+ key: e.nativeEvent.key,
439
+ preventDefault: () => {
440
+ }
441
+ });
442
+ }
443
+ },
444
+ editable: !disabled,
445
+ multiline: true,
446
+ numberOfLines: rows || 4,
447
+ style: [
448
+ {
449
+ color,
450
+ fontSize: typeof fontSize === "number" ? fontSize : void 0,
451
+ flex: 1,
452
+ padding: 0,
453
+ textAlignVertical: "top",
454
+ textAlign: style?.textAlign || "left"
455
+ },
456
+ style
457
+ ],
458
+ placeholderTextColor,
459
+ maxLength,
460
+ testID: dataTestId || id,
461
+ accessibilityLabel: ariaLabel,
462
+ accessibilityHint: ariaDescribedBy,
463
+ accessibilityState: {
464
+ disabled: disabled || ariaDisabled
465
+ },
466
+ accessible: true
467
+ }
468
+ );
469
+ }
470
+ );
471
+ TextAreaPrimitive.displayName = "TextAreaPrimitive";
472
+
473
+ // src/Checkbox.tsx
474
+ import { useDesignSystem, useId } from "@xsolla/xui-core";
475
+ import { Check, Minus } from "@xsolla/xui-icons";
476
+ import { jsx as jsx8, jsxs } from "react/jsx-runtime";
477
+ var iconSizeMap = {
478
+ s: 12,
479
+ m: 14,
480
+ l: 16,
481
+ xl: 18
482
+ };
483
+ var checkboxSizeMap = {
484
+ s: 16,
485
+ m: 18,
486
+ l: 20,
487
+ xl: 22
488
+ };
489
+ var labelGapMap = {
490
+ s: 8,
491
+ m: 8,
492
+ l: 10,
493
+ xl: 12
494
+ };
495
+ var textGapMap = {
496
+ s: 0,
497
+ m: 2,
498
+ l: 2,
499
+ xl: 4
500
+ };
501
+ var fontSizeMap = {
502
+ s: 14,
503
+ m: 16,
504
+ l: 18,
505
+ xl: 18
506
+ };
507
+ var lineHeightMap = {
508
+ s: 16,
509
+ m: 18,
510
+ l: 20,
511
+ xl: 22
512
+ };
513
+ var descriptionFontSizeMap = {
514
+ s: 12,
515
+ m: 14,
516
+ l: 16,
517
+ xl: 16
518
+ };
519
+ var descriptionLineHeightMap = {
520
+ s: 14,
521
+ m: 16,
522
+ l: 18,
523
+ xl: 18
524
+ };
525
+ var Checkbox = forwardRef3(
526
+ function Checkbox2({
527
+ children,
528
+ size = "m",
529
+ checked,
530
+ indeterminate = false,
531
+ description,
532
+ errorMessage,
533
+ error,
534
+ disabled,
535
+ name,
536
+ value,
537
+ onChange,
538
+ id: providedId,
539
+ "aria-label": ariaLabel
540
+ }, ref) {
541
+ const { theme } = useDesignSystem();
542
+ const containerRef = useRef(null);
543
+ const [internalChecked, setInternalChecked] = useState(false);
544
+ const rawId = useId();
545
+ const safeId = rawId.replace(/:/g, "");
546
+ const checkboxId = providedId || `checkbox-${safeId}`;
547
+ const labelId = `${checkboxId}-label`;
548
+ const descriptionId = `${checkboxId}-description`;
549
+ const errorId = `${checkboxId}-error`;
550
+ const isControlled = checked !== void 0;
551
+ const isChecked = isControlled ? checked : internalChecked;
552
+ useImperativeHandle(
553
+ ref,
554
+ () => ({
555
+ focus: () => containerRef.current?.focus(),
556
+ blur: () => containerRef.current?.blur()
557
+ }),
558
+ []
559
+ );
560
+ const handleToggle = () => {
561
+ if (disabled) return;
562
+ const newChecked = indeterminate ? true : !isChecked;
563
+ if (!isControlled) {
564
+ setInternalChecked(newChecked);
565
+ }
566
+ onChange?.({
567
+ target: {
568
+ checked: newChecked,
569
+ name,
570
+ value
571
+ }
572
+ });
573
+ };
574
+ const handleKeyDown = (event) => {
575
+ const key = event.key;
576
+ const isSpace = key === " " || key === "Spacebar" || key === "Space";
577
+ if (isSpace || key === "Enter") {
578
+ event.preventDefault();
579
+ handleToggle();
580
+ }
581
+ };
582
+ const isError = !!(errorMessage || error);
583
+ const hasTexts = !!children || !!description;
584
+ const isShowErrorMessage = !!errorMessage && hasTexts;
585
+ const isCheckedOrIndeterminate = isChecked || indeterminate;
586
+ const ariaDescribedByParts = [];
587
+ if (description) ariaDescribedByParts.push(descriptionId);
588
+ if (isShowErrorMessage) ariaDescribedByParts.push(errorId);
589
+ const ariaDescribedBy = ariaDescribedByParts.length > 0 ? ariaDescribedByParts.join(" ") : void 0;
590
+ const checkColors = theme.colors.control.check;
591
+ const faintColors = theme.colors.control.faint;
592
+ const textColors = theme.colors.control.text;
593
+ const contentColors = theme.colors.content;
594
+ const borderColors = theme.colors.border;
595
+ const getCheckboxBgColor = () => {
596
+ if (disabled) {
597
+ return checkColors.bgDisable;
598
+ }
599
+ if (isCheckedOrIndeterminate) {
600
+ return checkColors.bg;
601
+ }
602
+ return faintColors.bg;
603
+ };
604
+ const getBorderColor = () => {
605
+ if (isError && !isCheckedOrIndeterminate) {
606
+ return borderColors.alert;
607
+ }
608
+ if (isCheckedOrIndeterminate && !disabled) {
609
+ return checkColors.bg;
610
+ }
611
+ return faintColors.border;
612
+ };
613
+ const getLabelColor = () => {
614
+ if (disabled) return textColors.disable;
615
+ return textColors.primary;
616
+ };
617
+ const getDescriptionColor = () => {
618
+ if (disabled) return textColors.disable;
619
+ return contentColors.tertiary;
620
+ };
621
+ const getErrorMessageColor = () => {
622
+ return contentColors.alert.primary;
623
+ };
624
+ const getIconColor = () => {
625
+ if (disabled) return textColors.disable;
626
+ return textColors.faint;
627
+ };
628
+ const getAriaChecked = () => {
629
+ if (indeterminate) return "mixed";
630
+ return isChecked ? "true" : "false";
631
+ };
632
+ return /* @__PURE__ */ jsxs(
633
+ Box,
634
+ {
635
+ id: checkboxId,
636
+ ref: containerRef,
637
+ flexDirection: "row",
638
+ alignItems: "flex-start",
639
+ gap: labelGapMap[size],
640
+ onPress: handleToggle,
641
+ disabled,
642
+ role: "checkbox",
643
+ "aria-checked": getAriaChecked(),
644
+ "aria-disabled": disabled || void 0,
645
+ "aria-invalid": isError || void 0,
646
+ "aria-describedby": ariaDescribedBy,
647
+ "aria-labelledby": children ? labelId : void 0,
648
+ "aria-label": !children ? ariaLabel : void 0,
649
+ tabIndex: disabled ? -1 : 0,
650
+ onKeyDown: handleKeyDown,
651
+ "data-testid": "checkbox",
652
+ children: [
653
+ /* @__PURE__ */ jsx8(
654
+ Box,
655
+ {
656
+ width: checkboxSizeMap[size],
657
+ height: checkboxSizeMap[size],
658
+ backgroundColor: getCheckboxBgColor(),
659
+ borderColor: getBorderColor(),
660
+ borderWidth: 2,
661
+ borderRadius: 2,
662
+ alignItems: "center",
663
+ justifyContent: "center",
664
+ flexShrink: 0,
665
+ hoverStyle: !disabled ? {
666
+ backgroundColor: isCheckedOrIndeterminate ? checkColors.bgHover : faintColors.bgHover,
667
+ borderColor: isError && !isCheckedOrIndeterminate ? borderColors.alert : isCheckedOrIndeterminate ? checkColors.bgHover : faintColors.borderHover
668
+ } : void 0,
669
+ "data-testid": "checkbox__box",
670
+ children: isCheckedOrIndeterminate && (indeterminate ? /* @__PURE__ */ jsx8(Minus, { size: iconSizeMap[size], color: getIconColor() }) : /* @__PURE__ */ jsx8(Check, { size: iconSizeMap[size], color: getIconColor() }))
671
+ }
672
+ ),
673
+ hasTexts && /* @__PURE__ */ jsxs(
674
+ Box,
675
+ {
676
+ flexDirection: "column",
677
+ alignItems: "flex-start",
678
+ gap: textGapMap[size],
679
+ children: [
680
+ children && /* @__PURE__ */ jsx8(
681
+ Text,
682
+ {
683
+ id: labelId,
684
+ color: getLabelColor(),
685
+ fontSize: fontSizeMap[size],
686
+ lineHeight: lineHeightMap[size],
687
+ fontWeight: 400,
688
+ "data-testid": "checkbox__label",
689
+ children
690
+ }
691
+ ),
692
+ description && /* @__PURE__ */ jsx8(
693
+ Text,
694
+ {
695
+ id: descriptionId,
696
+ color: getDescriptionColor(),
697
+ fontSize: descriptionFontSizeMap[size],
698
+ lineHeight: descriptionLineHeightMap[size],
699
+ "data-testid": "checkbox__description",
700
+ children: description
701
+ }
702
+ ),
703
+ isShowErrorMessage && /* @__PURE__ */ jsx8(
704
+ Text,
705
+ {
706
+ id: errorId,
707
+ role: "alert",
708
+ color: getErrorMessageColor(),
709
+ fontSize: descriptionFontSizeMap[size],
710
+ lineHeight: descriptionLineHeightMap[size],
711
+ "data-testid": "checkbox__error",
712
+ children: errorMessage
713
+ }
714
+ )
715
+ ]
716
+ }
717
+ )
718
+ ]
719
+ }
720
+ );
721
+ }
722
+ );
723
+ Checkbox.displayName = "Checkbox";
724
+ export {
725
+ Checkbox
726
+ };
727
+ //# sourceMappingURL=index.mjs.map