@xsolla/xui-segmented 0.220.0 → 0.221.1

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/README.md CHANGED
@@ -143,6 +143,7 @@ import { Segmented } from "@xsolla/xui-segmented";
143
143
  onChange={handleChange} // Selection change handler
144
144
  size="md" // Size variant
145
145
  fullWidth={false} // Expand to container width
146
+ overflow="ellipsis" // Long-label handling: "ellipsis" | "wrap"
146
147
  />;
147
148
  ```
148
149
 
@@ -195,6 +196,41 @@ export default function DisabledItemSegmented() {
195
196
  }
196
197
  ```
197
198
 
199
+ ### Long Labels
200
+
201
+ Labels that don't fit their segment are never silently clipped. Choose how they adapt with `overflow`:
202
+
203
+ - `"ellipsis"` (default) — the label stays on one line and is truncated with `…`. On web the full label is shown as a native tooltip. The control keeps its standard height.
204
+ - `"wrap"` — the label wraps onto more lines (balanced on web) and the control grows in height only when a label actually needs it.
205
+
206
+ Short labels render exactly the same in both modes.
207
+
208
+ ```tsx
209
+ import * as React from "react";
210
+ import { Segmented } from "@xsolla/xui-segmented";
211
+
212
+ export default function LongLabelSegmented() {
213
+ const [active, setActive] = React.useState("existing");
214
+
215
+ return (
216
+ <div style={{ width: 664 }}>
217
+ <Segmented
218
+ fullWidth
219
+ size="sm"
220
+ overflow="wrap"
221
+ items={[
222
+ { id: "existing", label: "Spiel aus einem bestehenden Projekt hinzufügen" },
223
+ { id: "import", label: "Spiel aus einem anderen Store importieren" },
224
+ { id: "new", label: "Neues Projekt erstellen" },
225
+ ]}
226
+ activeId={active}
227
+ onChange={setActive}
228
+ />
229
+ </div>
230
+ );
231
+ }
232
+ ```
233
+
198
234
  ## API Reference
199
235
 
200
236
  ### Segmented
@@ -209,6 +245,7 @@ export default function DisabledItemSegmented() {
209
245
  | onChange | `(id: string) => void` | - | Selection change handler. |
210
246
  | size | `"xl" \| "lg" \| "md" \| "sm"` | `"md"` | Size variant. |
211
247
  | fullWidth | `boolean` | `false` | Expand segments to fill container width. |
248
+ | overflow | `"ellipsis" \| "wrap"` | `"ellipsis"` | How labels that don't fit are handled. See [Long Labels](#long-labels). |
212
249
  | id | `string` | - | HTML id attribute. |
213
250
  | testID | `string` | - | Test identifier. |
214
251
 
@@ -235,6 +272,8 @@ interface SegmentedItemType {
235
272
  ## Behavior
236
273
 
237
274
  - Active segment has elevated background with smooth sliding animation
275
+ - The sliding indicator re-measures when the items or the container resize (web font swap, viewport resize, label wrap), so it always matches the active segment's size and position
276
+ - Long labels either truncate with an ellipsis or wrap, depending on `overflow` — they are never clipped
238
277
  - Disabled segments show reduced opacity
239
278
  - Keyboard navigation wraps around
240
279
  - Hover effect on non-active segments
@@ -13,6 +13,14 @@ interface SegmentedItemType {
13
13
  /** Accessible label for screen readers */
14
14
  "aria-label"?: string;
15
15
  }
16
+ /**
17
+ * How a label that does not fit its segment is handled.
18
+ * - `"ellipsis"`: stays on one line and is truncated with `…`. The full label
19
+ * is shown as a native tooltip on web. Control height never changes.
20
+ * - `"wrap"`: wraps onto as many lines as it needs (balanced on web). The
21
+ * control grows in height only when a label actually wraps.
22
+ */
23
+ type SegmentedOverflow = "ellipsis" | "wrap";
16
24
  interface SegmentedProps extends ThemeOverrideProps {
17
25
  /** Array of items */
18
26
  items: SegmentedItemType[];
@@ -26,10 +34,17 @@ interface SegmentedProps extends ThemeOverrideProps {
26
34
  testID?: string;
27
35
  /** Full width of the container */
28
36
  fullWidth?: boolean;
37
+ /**
38
+ * How labels that don't fit are handled: `"ellipsis"` truncates on one line
39
+ * (full text in a tooltip on web), `"wrap"` wraps the label and lets the
40
+ * control grow in height. Short labels render identically in both modes.
41
+ * @default "ellipsis"
42
+ */
43
+ overflow?: SegmentedOverflow;
29
44
  }
30
45
  /**
31
46
  * Segmented - A control for switching between related views or filters
32
47
  */
33
48
  declare const Segmented: React.FC<SegmentedProps>;
34
49
 
35
- export { Segmented, type SegmentedItemType, type SegmentedProps };
50
+ export { Segmented, type SegmentedItemType, type SegmentedOverflow, type SegmentedProps };
package/native/index.d.ts CHANGED
@@ -13,6 +13,14 @@ interface SegmentedItemType {
13
13
  /** Accessible label for screen readers */
14
14
  "aria-label"?: string;
15
15
  }
16
+ /**
17
+ * How a label that does not fit its segment is handled.
18
+ * - `"ellipsis"`: stays on one line and is truncated with `…`. The full label
19
+ * is shown as a native tooltip on web. Control height never changes.
20
+ * - `"wrap"`: wraps onto as many lines as it needs (balanced on web). The
21
+ * control grows in height only when a label actually wraps.
22
+ */
23
+ type SegmentedOverflow = "ellipsis" | "wrap";
16
24
  interface SegmentedProps extends ThemeOverrideProps {
17
25
  /** Array of items */
18
26
  items: SegmentedItemType[];
@@ -26,10 +34,17 @@ interface SegmentedProps extends ThemeOverrideProps {
26
34
  testID?: string;
27
35
  /** Full width of the container */
28
36
  fullWidth?: boolean;
37
+ /**
38
+ * How labels that don't fit are handled: `"ellipsis"` truncates on one line
39
+ * (full text in a tooltip on web), `"wrap"` wraps the label and lets the
40
+ * control grow in height. Short labels render identically in both modes.
41
+ * @default "ellipsis"
42
+ */
43
+ overflow?: SegmentedOverflow;
29
44
  }
30
45
  /**
31
46
  * Segmented - A control for switching between related views or filters
32
47
  */
33
48
  declare const Segmented: React.FC<SegmentedProps>;
34
49
 
35
- export { Segmented, type SegmentedItemType, type SegmentedProps };
50
+ export { Segmented, type SegmentedItemType, type SegmentedOverflow, type SegmentedProps };
package/native/index.js CHANGED
@@ -386,30 +386,64 @@ var Segmented = ({
386
386
  id,
387
387
  testID,
388
388
  fullWidth = false,
389
+ overflow = "ellipsis",
389
390
  themeMode,
390
391
  themeProductContext
391
392
  }) => {
392
393
  const { theme } = (0, import_xui_core.useResolvedTheme)({ themeMode, themeProductContext });
393
394
  const sizeStyles = theme.sizing.segmented(size);
395
+ const isWrap = overflow === "wrap";
394
396
  const containerId = id ? `${id}-container` : void 0;
395
397
  const itemRefs = (0, import_react2.useRef)([]);
396
398
  const containerRef = (0, import_react2.useRef)(null);
397
- const [indicatorStyle, setIndicatorStyle] = (0, import_react2.useState)({ left: 0, width: 0, initialized: false });
398
- (0, import_react2.useEffect)(() => {
399
+ const [indicatorStyle, setIndicatorStyle] = (0, import_react2.useState)({
400
+ left: 0,
401
+ top: 0,
402
+ width: 0,
403
+ height: 0,
404
+ initialized: false
405
+ });
406
+ const activeIndex = items.findIndex((item) => item.id === activeId);
407
+ const updateIndicator = (0, import_react2.useCallback)(() => {
399
408
  if (!isWeb) return;
400
- const activeIndex = items.findIndex((item) => item.id === activeId);
401
409
  const activeItemEl = itemRefs.current[activeIndex];
402
410
  const containerEl = containerRef.current;
403
- if (activeItemEl && containerEl) {
404
- const containerRect = containerEl.getBoundingClientRect();
405
- const itemRect = activeItemEl.getBoundingClientRect();
406
- setIndicatorStyle({
407
- left: itemRect.left - containerRect.left,
408
- width: itemRect.width,
409
- initialized: true
410
- });
411
- }
412
- }, [activeId, items]);
411
+ if (!activeItemEl || !containerEl) return;
412
+ const containerRect = containerEl.getBoundingClientRect();
413
+ const itemRect = activeItemEl.getBoundingClientRect();
414
+ const next = {
415
+ left: itemRect.left - containerRect.left - containerEl.clientLeft,
416
+ top: itemRect.top - containerRect.top - containerEl.clientTop,
417
+ width: itemRect.width,
418
+ height: itemRect.height
419
+ };
420
+ setIndicatorStyle(
421
+ (prev) => prev.initialized && prev.left === next.left && prev.top === next.top && prev.width === next.width && prev.height === next.height ? prev : { ...next, initialized: true }
422
+ );
423
+ }, [activeIndex]);
424
+ (0, import_react2.useEffect)(() => {
425
+ if (!isWeb) return;
426
+ updateIndicator();
427
+ if (typeof ResizeObserver === "undefined") return;
428
+ const observer = new ResizeObserver(() => updateIndicator());
429
+ if (containerRef.current) observer.observe(containerRef.current);
430
+ itemRefs.current.slice(0, items.length).forEach((el) => {
431
+ if (el) observer.observe(el);
432
+ });
433
+ return () => observer.disconnect();
434
+ }, [updateIndicator, items.length, overflow, size, fullWidth]);
435
+ (0, import_react2.useEffect)(() => {
436
+ if (!isWeb || typeof document === "undefined") return;
437
+ const fonts = document.fonts;
438
+ if (!fonts) return;
439
+ let cancelled = false;
440
+ fonts.ready.then(() => {
441
+ if (!cancelled) updateIndicator();
442
+ });
443
+ return () => {
444
+ cancelled = true;
445
+ };
446
+ }, [updateIndicator]);
413
447
  const enabledIndices = items.map((item, index) => !item.disabled ? index : -1).filter((i) => i !== -1);
414
448
  const focusItem = (0, import_react2.useCallback)((index) => {
415
449
  const element = itemRefs.current[index];
@@ -450,6 +484,9 @@ var Segmented = ({
450
484
  },
451
485
  [enabledIndices, focusItem, onChange, items]
452
486
  );
487
+ const disableColors = theme.colors.control.disable;
488
+ const isActiveItemDisabled = items.find((item) => item.id === activeId)?.disabled === true;
489
+ const indicatorBg = isActiveItemDisabled ? disableColors.bgActive : theme.colors.control.segmented.bgActive;
453
490
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
454
491
  Box,
455
492
  {
@@ -460,11 +497,12 @@ var Segmented = ({
460
497
  containerRef.current = el;
461
498
  },
462
499
  flexDirection: "row",
463
- alignItems: "center",
500
+ alignItems: "stretch",
464
501
  flexShrink: 0,
465
502
  position: "relative",
466
503
  width: fullWidth ? "100%" : "fit-content",
467
- height: sizeStyles.height,
504
+ maxWidth: "100%",
505
+ minHeight: sizeStyles.height,
468
506
  backgroundColor: theme.colors.control.segmented.bg,
469
507
  borderRadius: sizeStyles.containerRadius,
470
508
  padding: sizeStyles.containerPadding,
@@ -478,13 +516,14 @@ var Segmented = ({
478
516
  {
479
517
  position: "absolute",
480
518
  zIndex: 0,
481
- height: sizeStyles.itemHeight,
482
- backgroundColor: theme.colors.control.segmented.bgActive,
519
+ backgroundColor: indicatorBg,
483
520
  borderRadius: sizeStyles.itemRadius,
484
521
  style: {
485
522
  left: indicatorStyle.left,
523
+ top: indicatorStyle.top,
486
524
  width: indicatorStyle.width,
487
- transition: "left 200ms ease-out, width 200ms ease-out",
525
+ height: indicatorStyle.height,
526
+ transition: "left 200ms ease-out, top 200ms ease-out, width 200ms ease-out, height 200ms ease-out",
488
527
  pointerEvents: "none"
489
528
  },
490
529
  "aria-hidden": true
@@ -499,7 +538,7 @@ var Segmented = ({
499
538
  onChange(item.id);
500
539
  }
501
540
  };
502
- const textColor = isDisabled ? theme.colors.control.segmented.textDisable : theme.colors.control.segmented.text;
541
+ const textColor = isDisabled ? isActive ? disableColors.contentActive : theme.colors.control.segmented.textDisable : theme.colors.control.segmented.text;
503
542
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
504
543
  Box,
505
544
  {
@@ -517,17 +556,18 @@ var Segmented = ({
517
556
  onPress: handlePress,
518
557
  onKeyDown: (e) => handleKeyDown(e, index),
519
558
  flex: fullWidth ? 1 : void 0,
520
- flexShrink: 0,
559
+ flexShrink: 1,
560
+ minWidth: 0,
521
561
  position: "relative",
522
562
  zIndex: 1,
523
- height: sizeStyles.itemHeight,
563
+ minHeight: sizeStyles.itemHeight,
524
564
  paddingHorizontal: sizeStyles.itemPaddingHorizontal,
525
565
  paddingVertical: sizeStyles.itemPaddingVertical,
526
566
  flexDirection: "row",
527
567
  alignItems: "center",
528
568
  justifyContent: "center",
529
569
  gap: sizeStyles.gap,
530
- backgroundColor: !isWeb && isActive ? theme.colors.control.segmented.bgActive : "transparent",
570
+ backgroundColor: !isWeb && isActive ? indicatorBg : "transparent",
531
571
  borderRadius: sizeStyles.itemRadius,
532
572
  cursor: isDisabled ? "not-allowed" : "pointer",
533
573
  hoverStyle: !isDisabled && !isActive ? {
@@ -539,17 +579,32 @@ var Segmented = ({
539
579
  outlineOffset: -2
540
580
  },
541
581
  children: [
542
- item.icon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { size: sizeStyles.iconSize, color: textColor, "aria-hidden": true, children: item.icon }),
543
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
582
+ item.icon && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Box, { flexShrink: 0, alignItems: "center", justifyContent: "center", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Icon, { size: sizeStyles.iconSize, color: textColor, "aria-hidden": true, children: item.icon }) }),
583
+ isWrap ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
584
+ Text,
585
+ {
586
+ color: textColor,
587
+ fontSize: sizeStyles.fontSize,
588
+ lineHeight: sizeStyles.lineHeight,
589
+ fontWeight: "500",
590
+ textAlign: "center",
591
+ whiteSpace: "normal",
592
+ style: isWeb ? {
593
+ minWidth: 0,
594
+ overflowWrap: "anywhere",
595
+ textWrap: "balance"
596
+ } : void 0,
597
+ children: item.label
598
+ }
599
+ ) : /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
544
600
  Text,
545
601
  {
546
602
  color: textColor,
547
603
  fontSize: sizeStyles.fontSize,
548
604
  fontWeight: "500",
549
605
  textAlign: "center",
550
- whiteSpace: "nowrap",
551
- overflow: "hidden",
552
- textOverflow: "ellipsis",
606
+ numberOfLines: 1,
607
+ title: item.label,
553
608
  children: item.label
554
609
  }
555
610
  )
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.tsx","../../src/Segmented.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./Segmented\";\n","import React, { useCallback, useRef, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\n\nexport interface SegmentedItemType {\n /** Unique identifier for the item */\n id: string;\n /** Display label for the item */\n label: string;\n /** Optional icon to display */\n icon?: React.ReactNode;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers */\n \"aria-label\"?: string;\n}\n\nexport interface SegmentedProps extends ThemeOverrideProps {\n /** Array of items */\n items: SegmentedItemType[];\n /** ID of the currently active item */\n activeId?: string;\n /** Callback when an item is selected */\n onChange?: (id: string) => void;\n /** Size variant */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n id?: string;\n testID?: string;\n /** Full width of the container */\n fullWidth?: boolean;\n}\n\n/**\n * Segmented - A control for switching between related views or filters\n */\nexport const Segmented: React.FC<SegmentedProps> = ({\n items,\n activeId,\n onChange,\n size = \"md\",\n id,\n testID,\n fullWidth = false,\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizeStyles = theme.sizing.segmented(size);\n\n const containerId = id ? `${id}-container` : undefined;\n const itemRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for animation (web only)\n const [indicatorStyle, setIndicatorStyle] = useState<{\n left: number;\n width: number;\n initialized: boolean;\n }>({ left: 0, width: 0, initialized: false });\n\n // Update indicator position when active item changes (web only)\n useEffect(() => {\n if (!isWeb) return;\n\n const activeIndex = items.findIndex((item) => item.id === activeId);\n const activeItemEl = itemRefs.current[activeIndex];\n const containerEl = containerRef.current;\n\n if (activeItemEl && containerEl) {\n const containerRect = containerEl.getBoundingClientRect();\n const itemRect = activeItemEl.getBoundingClientRect();\n\n setIndicatorStyle({\n left: itemRect.left - containerRect.left,\n width: itemRect.width,\n initialized: true,\n });\n }\n }, [activeId, items]);\n\n const enabledIndices = items\n .map((item, index) => (!item.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n const focusItem = useCallback((index: number) => {\n const element = itemRefs.current[index];\n if (element) {\n element.focus();\n }\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusItem(nextEnabledIndex);\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusItem(prevEnabledIndex);\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (onChange && !items[currentIndex].disabled) {\n onChange(items[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusItem, onChange, items]\n );\n\n return (\n <Box\n id={containerId}\n role=\"radiogroup\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"center\"\n flexShrink={0}\n position=\"relative\"\n width={fullWidth ? \"100%\" : \"fit-content\"}\n height={sizeStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={sizeStyles.containerRadius}\n padding={sizeStyles.containerPadding}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n height={sizeStyles.itemHeight}\n backgroundColor={theme.colors.control.segmented.bgActive}\n borderRadius={sizeStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n width: indicatorStyle.width,\n transition: \"left 200ms ease-out, width 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {items.map((item, index) => {\n const isActive = item.id === activeId;\n const isDisabled = item.disabled;\n const itemId = id ? `${id}-item-${item.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(item.id);\n }\n };\n\n const textColor = isDisabled\n ? theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={item.id}\n as=\"button\"\n role=\"radio\"\n id={itemId}\n aria-checked={isActive}\n aria-disabled={isDisabled}\n aria-label={item[\"aria-label\"] || item.label}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n itemRefs.current[index] = el;\n }}\n onPress={handlePress}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={fullWidth ? 1 : undefined}\n flexShrink={0}\n position=\"relative\"\n zIndex={1}\n height={sizeStyles.itemHeight}\n paddingHorizontal={sizeStyles.itemPaddingHorizontal}\n paddingVertical={sizeStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={sizeStyles.gap}\n backgroundColor={\n !isWeb && isActive\n ? theme.colors.control.segmented.bgActive\n : \"transparent\"\n }\n borderRadius={sizeStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {item.icon && (\n <Icon size={sizeStyles.iconSize} color={textColor} aria-hidden>\n {item.icon}\n </Icon>\n )}\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n fontWeight=\"500\"\n textAlign=\"center\"\n whiteSpace=\"nowrap\"\n overflow=\"hidden\"\n textOverflow=\"ellipsis\"\n >\n {item.label}\n </Text>\n </Box>\n );\n })}\n </Box>\n );\n};\n\nSegmented.displayName = \"Segmented\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n display,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n display: toNativeDisplay(display),\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../src/index.tsx","../../src/Segmented.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../../../foundation/primitives-native/src/Icon.tsx","../../../../foundation/primitives-native/src/index.tsx"],"sourcesContent":["export * from \"./Segmented\";\n","import React, { useCallback, useRef, useState, useEffect } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text, Icon, isWeb } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\n\nexport interface SegmentedItemType {\n /** Unique identifier for the item */\n id: string;\n /** Display label for the item */\n label: string;\n /** Optional icon to display */\n icon?: React.ReactNode;\n /** Whether the item is disabled */\n disabled?: boolean;\n /** Accessible label for screen readers */\n \"aria-label\"?: string;\n}\n\n/**\n * How a label that does not fit its segment is handled.\n * - `\"ellipsis\"`: stays on one line and is truncated with `…`. The full label\n * is shown as a native tooltip on web. Control height never changes.\n * - `\"wrap\"`: wraps onto as many lines as it needs (balanced on web). The\n * control grows in height only when a label actually wraps.\n */\nexport type SegmentedOverflow = \"ellipsis\" | \"wrap\";\n\nexport interface SegmentedProps extends ThemeOverrideProps {\n /** Array of items */\n items: SegmentedItemType[];\n /** ID of the currently active item */\n activeId?: string;\n /** Callback when an item is selected */\n onChange?: (id: string) => void;\n /** Size variant */\n size?: \"xl\" | \"lg\" | \"md\" | \"sm\";\n id?: string;\n testID?: string;\n /** Full width of the container */\n fullWidth?: boolean;\n /**\n * How labels that don't fit are handled: `\"ellipsis\"` truncates on one line\n * (full text in a tooltip on web), `\"wrap\"` wraps the label and lets the\n * control grow in height. Short labels render identically in both modes.\n * @default \"ellipsis\"\n */\n overflow?: SegmentedOverflow;\n}\n\ninterface IndicatorStyle {\n left: number;\n top: number;\n width: number;\n height: number;\n initialized: boolean;\n}\n\n/**\n * Segmented - A control for switching between related views or filters\n */\nexport const Segmented: React.FC<SegmentedProps> = ({\n items,\n activeId,\n onChange,\n size = \"md\",\n id,\n testID,\n fullWidth = false,\n overflow = \"ellipsis\",\n themeMode,\n themeProductContext,\n}) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizeStyles = theme.sizing.segmented(size);\n const isWrap = overflow === \"wrap\";\n\n const containerId = id ? `${id}-container` : undefined;\n const itemRefs = useRef<(HTMLElement | null)[]>([]);\n const containerRef = useRef<HTMLElement | null>(null);\n\n // Indicator position for animation (web only)\n const [indicatorStyle, setIndicatorStyle] = useState<IndicatorStyle>({\n left: 0,\n top: 0,\n width: 0,\n height: 0,\n initialized: false,\n });\n\n const activeIndex = items.findIndex((item) => item.id === activeId);\n\n // Measure the active item and move the indicator onto it (web only).\n // Positions are relative to the container's padding box (what\n // `position: absolute` resolves against), so the container border is\n // subtracted via clientLeft/clientTop.\n const updateIndicator = useCallback(() => {\n if (!isWeb) return;\n\n const activeItemEl = itemRefs.current[activeIndex];\n const containerEl = containerRef.current;\n if (!activeItemEl || !containerEl) return;\n\n const containerRect = containerEl.getBoundingClientRect();\n const itemRect = activeItemEl.getBoundingClientRect();\n\n const next = {\n left: itemRect.left - containerRect.left - containerEl.clientLeft,\n top: itemRect.top - containerRect.top - containerEl.clientTop,\n width: itemRect.width,\n height: itemRect.height,\n };\n\n setIndicatorStyle((prev) =>\n prev.initialized &&\n prev.left === next.left &&\n prev.top === next.top &&\n prev.width === next.width &&\n prev.height === next.height\n ? prev\n : { ...next, initialized: true }\n );\n }, [activeIndex]);\n\n // Re-measure when the active item changes, and whenever the container or\n // any item resizes afterwards (web font swap, viewport resize, label wrap).\n useEffect(() => {\n if (!isWeb) return;\n\n updateIndicator();\n\n if (typeof ResizeObserver === \"undefined\") return;\n\n const observer = new ResizeObserver(() => updateIndicator());\n if (containerRef.current) observer.observe(containerRef.current);\n itemRefs.current.slice(0, items.length).forEach((el) => {\n if (el) observer.observe(el);\n });\n\n return () => observer.disconnect();\n }, [updateIndicator, items.length, overflow, size, fullWidth]);\n\n // Web fonts can finish loading after the first measurement.\n useEffect(() => {\n if (!isWeb || typeof document === \"undefined\") return;\n const fonts = (document as Document & { fonts?: FontFaceSet }).fonts;\n if (!fonts) return;\n\n let cancelled = false;\n fonts.ready.then(() => {\n if (!cancelled) updateIndicator();\n });\n return () => {\n cancelled = true;\n };\n }, [updateIndicator]);\n\n const enabledIndices = items\n .map((item, index) => (!item.disabled ? index : -1))\n .filter((i) => i !== -1);\n\n const focusItem = useCallback((index: number) => {\n const element = itemRefs.current[index];\n if (element) {\n element.focus();\n }\n }, []);\n\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent, currentIndex: number) => {\n const currentEnabledIndex = enabledIndices.indexOf(currentIndex);\n\n switch (e.key) {\n case \"ArrowRight\":\n case \"ArrowDown\":\n e.preventDefault();\n {\n const nextEnabledIndex =\n currentEnabledIndex < enabledIndices.length - 1\n ? enabledIndices[currentEnabledIndex + 1]\n : enabledIndices[0];\n focusItem(nextEnabledIndex);\n }\n break;\n\n case \"ArrowLeft\":\n case \"ArrowUp\":\n e.preventDefault();\n {\n const prevEnabledIndex =\n currentEnabledIndex > 0\n ? enabledIndices[currentEnabledIndex - 1]\n : enabledIndices[enabledIndices.length - 1];\n focusItem(prevEnabledIndex);\n }\n break;\n\n case \"Enter\":\n case \" \":\n e.preventDefault();\n if (onChange && !items[currentIndex].disabled) {\n onChange(items[currentIndex].id);\n }\n break;\n\n default:\n break;\n }\n },\n [enabledIndices, focusItem, onChange, items]\n );\n\n // XUITSD-68: a disabled item that is also the active one has no\n // segmented-specific tokens in Figma, so the indicator and its label use the\n // shared control.disable active pair. Disabled inactive items keep\n // control.segmented.textDisable.\n const disableColors = theme.colors.control.disable;\n const isActiveItemDisabled =\n items.find((item) => item.id === activeId)?.disabled === true;\n const indicatorBg = isActiveItemDisabled\n ? disableColors.bgActive\n : theme.colors.control.segmented.bgActive;\n\n return (\n <Box\n id={containerId}\n role=\"radiogroup\"\n testID={testID}\n ref={(el: HTMLElement | null) => {\n containerRef.current = el;\n }}\n flexDirection=\"row\"\n alignItems=\"stretch\"\n flexShrink={0}\n position=\"relative\"\n width={fullWidth ? \"100%\" : \"fit-content\"}\n maxWidth=\"100%\"\n minHeight={sizeStyles.height}\n backgroundColor={theme.colors.control.segmented.bg}\n borderRadius={sizeStyles.containerRadius}\n padding={sizeStyles.containerPadding}\n borderWidth={1}\n borderColor={theme.colors.border.secondary}\n borderStyle=\"solid\"\n overflow=\"hidden\"\n >\n {/* Sliding indicator (web only) */}\n {isWeb && indicatorStyle.initialized && (\n <Box\n position=\"absolute\"\n zIndex={0}\n backgroundColor={indicatorBg}\n borderRadius={sizeStyles.itemRadius}\n style={{\n left: indicatorStyle.left,\n top: indicatorStyle.top,\n width: indicatorStyle.width,\n height: indicatorStyle.height,\n transition:\n \"left 200ms ease-out, top 200ms ease-out, width 200ms ease-out, height 200ms ease-out\",\n pointerEvents: \"none\",\n }}\n aria-hidden\n />\n )}\n {items.map((item, index) => {\n const isActive = item.id === activeId;\n const isDisabled = item.disabled;\n const itemId = id ? `${id}-item-${item.id}` : undefined;\n\n const handlePress = () => {\n if (!isDisabled && onChange) {\n onChange(item.id);\n }\n };\n\n const textColor = isDisabled\n ? isActive\n ? disableColors.contentActive\n : theme.colors.control.segmented.textDisable\n : theme.colors.control.segmented.text;\n\n return (\n <Box\n key={item.id}\n as=\"button\"\n role=\"radio\"\n id={itemId}\n aria-checked={isActive}\n aria-disabled={isDisabled}\n aria-label={item[\"aria-label\"] || item.label}\n tabIndex={isActive ? 0 : -1}\n disabled={isDisabled}\n ref={(el: HTMLElement | null) => {\n itemRefs.current[index] = el;\n }}\n onPress={handlePress}\n onKeyDown={(e: React.KeyboardEvent) => handleKeyDown(e, index)}\n flex={fullWidth ? 1 : undefined}\n flexShrink={1}\n minWidth={0}\n position=\"relative\"\n zIndex={1}\n minHeight={sizeStyles.itemHeight}\n paddingHorizontal={sizeStyles.itemPaddingHorizontal}\n paddingVertical={sizeStyles.itemPaddingVertical}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={sizeStyles.gap}\n backgroundColor={!isWeb && isActive ? indicatorBg : \"transparent\"}\n borderRadius={sizeStyles.itemRadius}\n cursor={isDisabled ? \"not-allowed\" : \"pointer\"}\n hoverStyle={\n !isDisabled && !isActive\n ? {\n backgroundColor: theme.colors.control.segmented.bgHover,\n }\n : undefined\n }\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineOffset: -2,\n }}\n >\n {item.icon && (\n <Box flexShrink={0} alignItems=\"center\" justifyContent=\"center\">\n <Icon size={sizeStyles.iconSize} color={textColor} aria-hidden>\n {item.icon}\n </Icon>\n </Box>\n )}\n {isWrap ? (\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n lineHeight={sizeStyles.lineHeight}\n fontWeight=\"500\"\n textAlign=\"center\"\n whiteSpace=\"normal\"\n style={\n isWeb\n ? ({\n minWidth: 0,\n overflowWrap: \"anywhere\",\n textWrap: \"balance\",\n } as React.CSSProperties)\n : undefined\n }\n >\n {item.label}\n </Text>\n ) : (\n <Text\n color={textColor}\n fontSize={sizeStyles.fontSize}\n fontWeight=\"500\"\n textAlign=\"center\"\n numberOfLines={1}\n title={item.label}\n >\n {item.label}\n </Text>\n )}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nSegmented.displayName = \"Segmented\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n display,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n display: toNativeDisplay(display),\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import React from \"react\";\nimport { View, ViewStyle } from \"react-native\";\nimport { IconProps } from \"@xsolla/xui-primitives-core\";\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n color,\n size,\n testID,\n \"data-testid\": dataTestId,\n}) => {\n const style: ViewStyle = {\n width: typeof size === \"number\" ? size : undefined,\n height: typeof size === \"number\" ? size : undefined,\n alignItems: \"center\",\n justifyContent: \"center\",\n };\n\n // On native, we try to pass the color down to children (like Text primitives)\n // to mimic the CSS inheritance behavior of the web version.\n const childrenWithProps = React.Children.map(children, (child) => {\n if (React.isValidElement(child)) {\n return React.cloneElement(child, {\n color: child.props.color || color,\n // Also pass size if child seems to be an icon that needs it\n size: child.props.size || size,\n });\n }\n return child;\n });\n\n return (\n <View style={style} testID={dataTestId || testID}>\n {childrenWithProps}\n </View>\n );\n};\n","export * from \"./Box\";\nexport * from \"./Text\";\nexport * from \"./Spinner\";\nexport * from \"./Icon\";\nexport * from \"./Divider\";\nexport * from \"./Input\";\nexport * from \"./TextArea\";\nexport * from \"./LinearGradient\";\n\nexport const isWeb = false;\nexport const isNative = true;\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_react_native","import_jsx_runtime","React","import_jsx_runtime"]}