@xsolla/xui-cell 0.225.0 → 0.226.0

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/native/index.mjs CHANGED
@@ -314,9 +314,17 @@ var Text = ({
314
314
  };
315
315
 
316
316
  // src/Cell.tsx
317
- import { useResolvedTheme } from "@xsolla/xui-core";
317
+ import {
318
+ controlSizeScale,
319
+ getTypographyVariant,
320
+ spacingScale,
321
+ useResolvedTheme
322
+ } from "@xsolla/xui-core";
318
323
  import { jsx as jsx3, jsxs } from "react/jsx-runtime";
319
- var CELL_PADDING = 8;
324
+ var CELL_PADDING = spacingScale["100"];
325
+ var CELL_GAP = spacingScale["150"];
326
+ var CELL_MIN_HEIGHT = controlSizeScale["650"];
327
+ var CELL_TEXT_ROW_GAP = spacingScale["25"];
320
328
  var CellRoot = forwardRef(
321
329
  ({
322
330
  children,
@@ -359,7 +367,7 @@ var CellRoot = forwardRef(
359
367
  };
360
368
  default:
361
369
  return {
362
- minHeight: 56,
370
+ minHeight: CELL_MIN_HEIGHT,
363
371
  hoverStyle: overlayState,
364
372
  pressStyle: overlayState
365
373
  };
@@ -374,7 +382,7 @@ var CellRoot = forwardRef(
374
382
  alignItems: "center",
375
383
  width: "100%",
376
384
  flexDirection: "row",
377
- gap: 12,
385
+ gap: CELL_GAP,
378
386
  onPress: disabled ? void 0 : onPress,
379
387
  cursor: disabled ? "not-allowed" : hasPress ? "pointer" : void 0,
380
388
  "aria-disabled": ariaDisabled ?? (disabled || void 0),
@@ -422,36 +430,59 @@ var CellContent = forwardRef(
422
430
  }
423
431
  );
424
432
  CellContent.displayName = "Cell.Content";
433
+ var resolveTextStyle = (productContext, variant) => {
434
+ const token = getTypographyVariant(productContext, variant);
435
+ if (!token) return {};
436
+ const lineHeight = parseFloat(String(token.lineHeight));
437
+ return {
438
+ fontSize: token.fontSize,
439
+ lineHeight: Number.isNaN(lineHeight) ? void 0 : lineHeight,
440
+ fontWeight: String(token.fontWeight)
441
+ };
442
+ };
425
443
  var CellTextRow = ({
426
444
  left,
427
445
  right,
428
446
  leftProps,
429
- rightProps
447
+ rightProps,
448
+ layout,
449
+ sideGap
430
450
  }) => {
431
451
  if (!left && !right) return null;
432
- return /* @__PURE__ */ jsxs(Box, { flexDirection: "row", gap: 12, alignItems: "center", width: "100%", children: [
433
- left != null && /* @__PURE__ */ jsx3(
434
- Box,
435
- {
436
- flexDirection: "row",
437
- alignItems: "center",
438
- gap: 2,
439
- style: { flex: 1, minWidth: 0, minHeight: 1 },
440
- children: typeof left === "string" ? /* @__PURE__ */ jsx3(Text, { ...leftProps, children: left }) : left
441
- }
442
- ),
443
- right != null && /* @__PURE__ */ jsx3(
444
- Box,
445
- {
446
- flexDirection: "row",
447
- alignItems: "center",
448
- justifyContent: "flex-end",
449
- gap: 2,
450
- style: { flex: 1, minWidth: 0, minHeight: 1 },
451
- children: typeof right === "string" ? /* @__PURE__ */ jsx3(Text, { ...rightProps, children: right }) : right
452
- }
453
- )
454
- ] });
452
+ const leftFlex = { flex: 1, minWidth: 0, minHeight: 1 };
453
+ const rightFlex = layout === "fill-start" ? { flexGrow: 0, flexShrink: 0, flexBasis: "auto", minHeight: 1 } : { flex: 1, minWidth: 0, minHeight: 1 };
454
+ return /* @__PURE__ */ jsxs(
455
+ Box,
456
+ {
457
+ flexDirection: "row",
458
+ gap: sideGap,
459
+ alignItems: "center",
460
+ width: "100%",
461
+ children: [
462
+ left != null && /* @__PURE__ */ jsx3(
463
+ Box,
464
+ {
465
+ flexDirection: "row",
466
+ alignItems: "center",
467
+ gap: CELL_TEXT_ROW_GAP,
468
+ style: leftFlex,
469
+ children: typeof left === "string" ? /* @__PURE__ */ jsx3(Text, { ...leftProps, children: left }) : left
470
+ }
471
+ ),
472
+ right != null && /* @__PURE__ */ jsx3(
473
+ Box,
474
+ {
475
+ flexDirection: "row",
476
+ alignItems: "center",
477
+ justifyContent: "flex-end",
478
+ gap: CELL_TEXT_ROW_GAP,
479
+ style: rightFlex,
480
+ children: typeof right === "string" ? /* @__PURE__ */ jsx3(Text, { ...rightProps, children: right }) : right
481
+ }
482
+ )
483
+ ]
484
+ }
485
+ );
455
486
  };
456
487
  var CellText = forwardRef(
457
488
  ({
@@ -461,14 +492,24 @@ var CellText = forwardRef(
461
492
  descriptionRight,
462
493
  caption,
463
494
  captionRight,
495
+ layout = "equal",
496
+ sideGap = CELL_GAP,
497
+ titleVariant = "bodyMdAccent",
498
+ titleRightVariant = "bodyXsParagraph",
499
+ descriptionVariant = "bodyXsParagraph",
500
+ descriptionRightVariant = "bodyXsParagraph",
501
+ captionVariant = "bodyXsParagraph",
502
+ captionRightVariant = "bodyXsParagraph",
464
503
  testID,
465
504
  themeMode,
466
505
  themeProductContext,
467
506
  ...props
468
507
  }, ref) => {
469
508
  const { theme } = useResolvedTheme({ themeMode, themeProductContext });
509
+ const productContext = theme.productContext;
470
510
  const hasDescriptions = description != null || descriptionRight != null;
471
511
  const hasCaptions = caption != null || captionRight != null;
512
+ const captionColor = theme.colors.content.tertiary;
472
513
  return /* @__PURE__ */ jsxs(
473
514
  Box,
474
515
  {
@@ -476,7 +517,7 @@ var CellText = forwardRef(
476
517
  ref,
477
518
  flexDirection: "column",
478
519
  justifyContent: "center",
479
- gap: 2,
520
+ gap: CELL_TEXT_ROW_GAP,
480
521
  ...props,
481
522
  style: { flex: 1, minWidth: 0, minHeight: 1, ...props.style },
482
523
  children: [
@@ -485,16 +526,10 @@ var CellText = forwardRef(
485
526
  {
486
527
  left: title,
487
528
  right: titleRight,
488
- leftProps: {
489
- fontWeight: "500",
490
- fontSize: 16,
491
- lineHeight: 20
492
- },
493
- rightProps: {
494
- fontWeight: "400",
495
- fontSize: 12,
496
- lineHeight: 18
497
- }
529
+ layout,
530
+ sideGap,
531
+ leftProps: resolveTextStyle(productContext, titleVariant),
532
+ rightProps: resolveTextStyle(productContext, titleRightVariant)
498
533
  }
499
534
  ),
500
535
  hasDescriptions && /* @__PURE__ */ jsx3(
@@ -502,16 +537,13 @@ var CellText = forwardRef(
502
537
  {
503
538
  left: description,
504
539
  right: descriptionRight,
505
- leftProps: {
506
- fontWeight: "400",
507
- fontSize: 12,
508
- lineHeight: 18
509
- },
510
- rightProps: {
511
- fontWeight: "400",
512
- fontSize: 12,
513
- lineHeight: 18
514
- }
540
+ layout,
541
+ sideGap,
542
+ leftProps: resolveTextStyle(productContext, descriptionVariant),
543
+ rightProps: resolveTextStyle(
544
+ productContext,
545
+ descriptionRightVariant
546
+ )
515
547
  }
516
548
  ),
517
549
  hasCaptions && /* @__PURE__ */ jsx3(
@@ -519,17 +551,15 @@ var CellText = forwardRef(
519
551
  {
520
552
  left: caption,
521
553
  right: captionRight,
554
+ layout,
555
+ sideGap,
522
556
  leftProps: {
523
- fontWeight: "400",
524
- fontSize: 12,
525
- lineHeight: 18,
526
- color: theme.colors.content.tertiary
557
+ ...resolveTextStyle(productContext, captionVariant),
558
+ color: captionColor
527
559
  },
528
560
  rightProps: {
529
- fontWeight: "400",
530
- fontSize: 12,
531
- lineHeight: 18,
532
- color: theme.colors.content.tertiary
561
+ ...resolveTextStyle(productContext, captionRightVariant),
562
+ color: captionColor
533
563
  }
534
564
  }
535
565
  )
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/Cell.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx"],"sourcesContent":["import { forwardRef, useMemo } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme } from \"@xsolla/xui-core\";\nimport {\n CellContentProps,\n CellProps,\n CellSlotProps,\n CellTextProps,\n CellView,\n} from \"./types\";\n\n/**\n * Figma \"Cell master\" (node 7222:5527) pads every bounded view by 8px.\n * Kept as a constant so the stroke and surface branches cannot drift apart.\n */\nconst CELL_PADDING = 8;\n\nconst CellRoot = forwardRef<any, CellProps>(\n (\n {\n children,\n view: viewProp,\n withBoard,\n disabled,\n onPress,\n style,\n testID,\n themeMode,\n themeProductContext,\n \"aria-disabled\": ariaDisabled,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const view: CellView = viewProp ?? (withBoard ? \"stroke\" : \"default\");\n\n const viewStyles = useMemo(() => {\n // Figma's Hover/Active state is overlay-mono laid over the resting fill,\n // not a swap to a different surface colour.\n const overlay = theme.colors.overlay.mono;\n\n // A disabled cell is not actionable, so it gets no pointer feedback.\n // Leaving these undefined (rather than `{}`) means Box's `&:hover` and\n // `&:active` blocks emit no declarations at all.\n const overlayState = disabled ? undefined : { backgroundColor: overlay };\n\n // The surface view already paints background-secondary, so its hover has\n // to stack overlay-mono ON TOP of that fill. A hover background-color\n // would replace it instead, so compose both layers with a flat\n // linear-gradient (same technique as Stepper's surface prop).\n const surfaceOverlayState = disabled\n ? undefined\n : {\n background: `linear-gradient(0deg, ${overlay} 0%, ${overlay} 100%), ${theme.colors.background.secondary}`,\n };\n\n switch (view) {\n case \"stroke\":\n return {\n borderRadius: theme.shape.cell.borderRadius,\n borderWidth: theme.shape.cell.borderWidth,\n borderColor: theme.colors.border.secondary,\n padding: CELL_PADDING,\n hoverStyle: overlayState,\n pressStyle: overlayState,\n };\n case \"surface\":\n return {\n backgroundColor: theme.colors.background.secondary,\n borderRadius: theme.shape.cell.borderRadius,\n padding: CELL_PADDING,\n hoverStyle: surfaceOverlayState,\n pressStyle: surfaceOverlayState,\n };\n default:\n return {\n minHeight: 56,\n hoverStyle: overlayState,\n pressStyle: overlayState,\n };\n }\n }, [view, theme, disabled]);\n\n const hasPress = !disabled && onPress != null;\n\n return (\n <Box\n testID={testID}\n ref={ref}\n alignItems=\"center\"\n width=\"100%\"\n flexDirection=\"row\"\n gap={12}\n // `disabled` is deliberately NOT forwarded to Box. Box maps it to\n // `opacity: 0.5` + `pointer-events: none`, which would dim the row and\n // make interactive children inside Cell.Slot (Radio, Button)\n // unclickable. Cell gates only its own affordances and leaves the\n // dimmed look to the consumer.\n onPress={disabled ? undefined : onPress}\n cursor={disabled ? \"not-allowed\" : hasPress ? \"pointer\" : undefined}\n aria-disabled={ariaDisabled ?? (disabled || undefined)}\n {...viewStyles}\n {...props}\n style={{ color: theme.colors.content.primary, ...style }}\n >\n {children}\n </Box>\n );\n }\n);\n\nCellRoot.displayName = \"Cell\";\n\nconst CellSlot = forwardRef<any, CellSlotProps>(\n ({ children, testID, ...props }, ref) => {\n return (\n <Box\n testID={testID}\n ref={ref}\n alignItems=\"center\"\n justifyContent=\"center\"\n flexDirection=\"row\"\n {...props}\n style={{ flexShrink: 0, ...props.style }}\n >\n {children}\n </Box>\n );\n }\n);\n\nCellSlot.displayName = \"Cell.Slot\";\n\nconst CellContent = forwardRef<any, CellContentProps>(\n ({ children, testID, ...props }, ref) => {\n return (\n <Box\n testID={testID}\n ref={ref}\n flexDirection=\"column\"\n justifyContent=\"center\"\n {...props}\n style={{ flex: 1, ...props.style }}\n >\n {children}\n </Box>\n );\n }\n);\n\nCellContent.displayName = \"Cell.Content\";\n\nconst CellTextRow = ({\n left,\n right,\n leftProps,\n rightProps,\n}: {\n left?: React.ReactNode;\n right?: React.ReactNode;\n leftProps?: Record<string, unknown>;\n rightProps?: Record<string, unknown>;\n}) => {\n if (!left && !right) return null;\n return (\n <Box flexDirection=\"row\" gap={12} alignItems=\"center\" width=\"100%\">\n {left != null && (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={2}\n style={{ flex: 1, minWidth: 0, minHeight: 1 }}\n >\n {typeof left === \"string\" ? <Text {...leftProps}>{left}</Text> : left}\n </Box>\n )}\n {right != null && (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"flex-end\"\n gap={2}\n style={{ flex: 1, minWidth: 0, minHeight: 1 }}\n >\n {typeof right === \"string\" ? (\n <Text {...rightProps}>{right}</Text>\n ) : (\n right\n )}\n </Box>\n )}\n </Box>\n );\n};\n\nconst CellText = forwardRef<any, CellTextProps>(\n (\n {\n title,\n titleRight,\n description,\n descriptionRight,\n caption,\n captionRight,\n testID,\n themeMode,\n themeProductContext,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const hasDescriptions = description != null || descriptionRight != null;\n const hasCaptions = caption != null || captionRight != null;\n\n return (\n <Box\n testID={testID}\n ref={ref}\n flexDirection=\"column\"\n justifyContent=\"center\"\n gap={2}\n {...props}\n style={{ flex: 1, minWidth: 0, minHeight: 1, ...props.style }}\n >\n <CellTextRow\n left={title}\n right={titleRight}\n leftProps={{\n fontWeight: \"500\",\n fontSize: 16,\n lineHeight: 20,\n }}\n rightProps={{\n fontWeight: \"400\",\n fontSize: 12,\n lineHeight: 18,\n }}\n />\n {hasDescriptions && (\n <CellTextRow\n left={description}\n right={descriptionRight}\n leftProps={{\n fontWeight: \"400\",\n fontSize: 12,\n lineHeight: 18,\n }}\n rightProps={{\n fontWeight: \"400\",\n fontSize: 12,\n lineHeight: 18,\n }}\n />\n )}\n {hasCaptions && (\n <CellTextRow\n left={caption}\n right={captionRight}\n leftProps={{\n fontWeight: \"400\",\n fontSize: 12,\n lineHeight: 18,\n color: theme.colors.content.tertiary,\n }}\n rightProps={{\n fontWeight: \"400\",\n fontSize: 12,\n lineHeight: 18,\n color: theme.colors.content.tertiary,\n }}\n />\n )}\n </Box>\n );\n }\n);\n\nCellText.displayName = \"Cell.Text\";\n\nexport const Cell = Object.assign(CellRoot, {\n Slot: CellSlot,\n Content: CellContent,\n Text: CellText,\n});\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"],"mappings":";AAAA,SAAS,YAAY,eAAe;;;ACCpC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAMK;AAqND;AAlNN,IAAM,0BAA6D;AAAA,EACjE,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,KAAK;AAAA,EACL,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,OAAO;AAAA,EACP,SAAS;AAAA,EACT,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,cAAc;AAAA,EACd,aAAa;AAAA,EACb,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,KAAK;AAAA,EACL,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AACT;AAGA,IAAM,aAAa,CAAC,QAAyD;AAC3E,MAAI,QAAQ,OAAW,QAAO;AAC9B,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAM,UAAU,sBAAsB,KAAK,GAAG;AAC9C,MAAI,QAAS,QAAO,OAAO,QAAQ,CAAC,CAAC;AACrC,QAAM,WAAW,OAAO,GAAG;AAC3B,SAAO,OAAO,SAAS,QAAQ,IAAI,WAAW;AAChD;AASA,IAAM,kBAAkB,CACtB,YAC0B,YAAY,SAAS,SAAS;AAEnD,IAAM,MAA0B,CAAC;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,oBAAoB,CAAC,aAAkC;AAAA,IAC3D,iBACE,WAAW,YAAY,kBACnB,WAAW,kBACX;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,YAAY,WAAW,MAAM;AAAA,IACtC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,gBAAgB,OAAO;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAK,WAAW,GAAG;AAAA,IACnB,GAAI;AAAA,EACN;AAEA,QAAM,cAAc,cAAc;AAKlC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,mBAAmB;AAAA,IACnB,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,IACb;AAAA,IACA,eAAe;AAAA,IACf,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,GAAG;AAAA,EACL,IAAI;AAEJ,QAAM,oBACH,OAAO,SAAS,YAAY,wBAAwB,IAAI,MACxD,OAAO,WAAW,WAAW;AAChC,QAAM,aAAa,QAAQ,YAAY,YAAY;AACnD,QAAM,qBAAqB;AAAA,IACzB,UAAU,cAAc;AAAA,IACxB,MAAM,QAAQ,QAAQ,KAAK;AAAA,EAC7B;AACA,QAAM,0BACJ,aAAa,YAAY,aAAa,cAAc,WAAW;AAGjE,MAAI,OAAO,SAAS,KAAK;AACvB,UAAM,aAAyB;AAAA,MAC7B;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAI;AAAA,IACN;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ,EAAE,KAAK,IAAI;AAAA,QACnB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,oBAAoB,OAAO,cAAc,WAAW,YAAY;AAAA,QAChE,YAAW;AAAA,QACV,GAAG;AAAA;AAAA,IACN;AAAA,EAEJ;AAIA,MAAI,WAAW,OAAO,UAAU;AAC9B,WACE;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,CAAC,cAAc,UAAU,UAAU;AAAA,QAC5C,UAAU;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO,CAAC,EAAE,QAAQ,MAAM,kBAAkB,OAAO;AAAA,QACjD,QAAQ;AAAA,QACR;AAAA,QACA,oBACE,OAAO,cAAc,WAAW,YAAY;AAAA,QAE9C;AAAA,QACA;AAAA,QACC,GAAG;AAAA,QAEH;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAO,kBAAkB;AAAA,MACzB,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB,OAAO,cAAc,WAAW,YAAY;AAAA,MAChE;AAAA,MACA;AAAA,MACC,GAAG;AAAA,MAEH;AAAA;AAAA,EACH;AAEJ;;;ACxRA;AAAA,EACE,QAAQ;AAAA,EAGR;AAAA,OACK;AAqEH,gBAAAA,YAAA;AAlEJ,IAAM,UAA6C;AAAA,EACjD,OAAO;AAAA,EACP,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,MAAM;AACR;AAEA,IAAM,oBAAoB,CACxB,UACuB;AACvB,MAAI,UAAU,OAAW,QAAO;AAChC,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,SAAS,WAAW,KAAK;AAC/B,SAAO,MAAM,MAAM,IAAI,SAAY;AACrC;AAEO,IAAM,OAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf,OAAO;AAAA,EACP,GAAG;AACL,MAAM;AACJ,MAAI,qBAAqB,aACrB,WAAW,MAAM,GAAG,EAAE,CAAC,EAAE,QAAQ,SAAS,EAAE,EAAE,KAAK,IACnD;AAEJ,MACE,uBAAuB,gBACvB,uBAAuB,qBACvB,uBAAuB,iBACvB;AACA,yBAAqB;AAAA,EACvB;AAEA,QAAM,gBAAgB,WAAW,QAAQ,SAAS;AAElD,QAAM,YAAuB;AAAA,IAC3B,OAAO,SAAS,eAAe;AAAA,IAC/B,UAAU,OAAO,aAAa,WAAW,WAAW;AAAA,IACpD;AAAA,IACA,YAAY;AAAA,IACZ,oBAAoB,MAAM;AAAA,IAC1B,WAAW,aAAa,eAAe;AAAA,IACvC,YAAY,kBAAkB,cAAc,eAAe,UAAU;AAAA,IACrE,WAAW;AAAA,MACT,eAAe;AAAA,IACjB;AAAA,IACA,cAAc;AAAA,MACZ,eAAe;AAAA,IACjB;AAAA,EACF;AAEA,QAAM,oBAAoB,OAAO,QAAQ,IAAI,IAAI;AAEjD,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,cAAc,UAAU;AAAA,MAChC;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;AFjFA,SAAS,wBAAwB;AAsF3B,gBAAAC,MA+EF,YA/EE;AAzEN,IAAM,eAAe;AAErB,IAAM,WAAW;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,iBAAiB;AAAA,IACjB,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,MAAM,IAAI,iBAAiB,EAAE,WAAW,oBAAoB,CAAC;AAErE,UAAM,OAAiB,aAAa,YAAY,WAAW;AAE3D,UAAM,aAAa,QAAQ,MAAM;AAG/B,YAAM,UAAU,MAAM,OAAO,QAAQ;AAKrC,YAAM,eAAe,WAAW,SAAY,EAAE,iBAAiB,QAAQ;AAMvE,YAAM,sBAAsB,WACxB,SACA;AAAA,QACE,YAAY,yBAAyB,OAAO,QAAQ,OAAO,WAAW,MAAM,OAAO,WAAW,SAAS;AAAA,MACzG;AAEJ,cAAQ,MAAM;AAAA,QACZ,KAAK;AACH,iBAAO;AAAA,YACL,cAAc,MAAM,MAAM,KAAK;AAAA,YAC/B,aAAa,MAAM,MAAM,KAAK;AAAA,YAC9B,aAAa,MAAM,OAAO,OAAO;AAAA,YACjC,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,YAAY;AAAA,UACd;AAAA,QACF,KAAK;AACH,iBAAO;AAAA,YACL,iBAAiB,MAAM,OAAO,WAAW;AAAA,YACzC,cAAc,MAAM,MAAM,KAAK;AAAA,YAC/B,SAAS;AAAA,YACT,YAAY;AAAA,YACZ,YAAY;AAAA,UACd;AAAA,QACF;AACE,iBAAO;AAAA,YACL,WAAW;AAAA,YACX,YAAY;AAAA,YACZ,YAAY;AAAA,UACd;AAAA,MACJ;AAAA,IACF,GAAG,CAAC,MAAM,OAAO,QAAQ,CAAC;AAE1B,UAAM,WAAW,CAAC,YAAY,WAAW;AAEzC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,YAAW;AAAA,QACX,OAAM;AAAA,QACN,eAAc;AAAA,QACd,KAAK;AAAA,QAML,SAAS,WAAW,SAAY;AAAA,QAChC,QAAQ,WAAW,gBAAgB,WAAW,YAAY;AAAA,QAC1D,iBAAe,iBAAiB,YAAY;AAAA,QAC3C,GAAG;AAAA,QACH,GAAG;AAAA,QACJ,OAAO,EAAE,OAAO,MAAM,OAAO,QAAQ,SAAS,GAAG,MAAM;AAAA,QAEtD;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEvB,IAAM,WAAW;AAAA,EACf,CAAC,EAAE,UAAU,QAAQ,GAAG,MAAM,GAAG,QAAQ;AACvC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,YAAW;AAAA,QACX,gBAAe;AAAA,QACf,eAAc;AAAA,QACb,GAAG;AAAA,QACJ,OAAO,EAAE,YAAY,GAAG,GAAG,MAAM,MAAM;AAAA,QAEtC;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEvB,IAAM,cAAc;AAAA,EAClB,CAAC,EAAE,UAAU,QAAQ,GAAG,MAAM,GAAG,QAAQ;AACvC,WACE,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,eAAc;AAAA,QACd,gBAAe;AAAA,QACd,GAAG;AAAA,QACJ,OAAO,EAAE,MAAM,GAAG,GAAG,MAAM,MAAM;AAAA,QAEhC;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;AAE1B,IAAM,cAAc,CAAC;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAKM;AACJ,MAAI,CAAC,QAAQ,CAAC,MAAO,QAAO;AAC5B,SACE,qBAAC,OAAI,eAAc,OAAM,KAAK,IAAI,YAAW,UAAS,OAAM,QACzD;AAAA,YAAQ,QACP,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,eAAc;AAAA,QACd,YAAW;AAAA,QACX,KAAK;AAAA,QACL,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,EAAE;AAAA,QAE3C,iBAAO,SAAS,WAAW,gBAAAA,KAAC,QAAM,GAAG,WAAY,gBAAK,IAAU;AAAA;AAAA,IACnE;AAAA,IAED,SAAS,QACR,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,eAAc;AAAA,QACd,YAAW;AAAA,QACX,gBAAe;AAAA,QACf,KAAK;AAAA,QACL,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,EAAE;AAAA,QAE3C,iBAAO,UAAU,WAChB,gBAAAA,KAAC,QAAM,GAAG,YAAa,iBAAM,IAE7B;AAAA;AAAA,IAEJ;AAAA,KAEJ;AAEJ;AAEA,IAAM,WAAW;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GACA,QACG;AACH,UAAM,EAAE,MAAM,IAAI,iBAAiB,EAAE,WAAW,oBAAoB,CAAC;AAErE,UAAM,kBAAkB,eAAe,QAAQ,oBAAoB;AACnE,UAAM,cAAc,WAAW,QAAQ,gBAAgB;AAEvD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,eAAc;AAAA,QACd,gBAAe;AAAA,QACf,KAAK;AAAA,QACJ,GAAG;AAAA,QACJ,OAAO,EAAE,MAAM,GAAG,UAAU,GAAG,WAAW,GAAG,GAAG,MAAM,MAAM;AAAA,QAE5D;AAAA,0BAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,WAAW;AAAA,gBACT,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,YAAY;AAAA,cACd;AAAA,cACA,YAAY;AAAA,gBACV,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,YAAY;AAAA,cACd;AAAA;AAAA,UACF;AAAA,UACC,mBACC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,WAAW;AAAA,gBACT,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,YAAY;AAAA,cACd;AAAA,cACA,YAAY;AAAA,gBACV,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,YAAY;AAAA,cACd;AAAA;AAAA,UACF;AAAA,UAED,eACC,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAM;AAAA,cACN,OAAO;AAAA,cACP,WAAW;AAAA,gBACT,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,OAAO,MAAM,OAAO,QAAQ;AAAA,cAC9B;AAAA,cACA,YAAY;AAAA,gBACV,YAAY;AAAA,gBACZ,UAAU;AAAA,gBACV,YAAY;AAAA,gBACZ,OAAO,MAAM,OAAO,QAAQ;AAAA,cAC9B;AAAA;AAAA,UACF;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEhB,IAAM,OAAO,OAAO,OAAO,UAAU;AAAA,EAC1C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,MAAM;AACR,CAAC;","names":["jsx","jsx"]}
1
+ {"version":3,"sources":["../../src/Cell.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx"],"sourcesContent":["import { forwardRef, useMemo } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport {\n controlSizeScale,\n getTypographyVariant,\n spacingScale,\n useResolvedTheme,\n} from \"@xsolla/xui-core\";\nimport {\n CellContentProps,\n CellProps,\n CellSlotProps,\n CellTextLayout,\n CellTextProps,\n CellTextVariant,\n CellView,\n} from \"./types\";\n\n/**\n * Figma \"Cell master\" (node 7222:5527) pads every bounded view by 8px\n * (`spacing/100`). Kept as a constant so the stroke and surface branches\n * cannot drift apart.\n */\nconst CELL_PADDING = spacingScale[\"100\"];\n/** Gap between slots, and between the left/right parts of a text row. */\nconst CELL_GAP = spacingScale[\"150\"];\n/** Minimum row height of the unbounded `default` view (`control-size/650`). */\nconst CELL_MIN_HEIGHT = controlSizeScale[\"650\"];\n/** Vertical gap between the rows of `Cell.Text`. */\nconst CELL_TEXT_ROW_GAP = spacingScale[\"25\"];\n\nconst CellRoot = forwardRef<any, CellProps>(\n (\n {\n children,\n view: viewProp,\n withBoard,\n disabled,\n onPress,\n style,\n testID,\n themeMode,\n themeProductContext,\n \"aria-disabled\": ariaDisabled,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const view: CellView = viewProp ?? (withBoard ? \"stroke\" : \"default\");\n\n const viewStyles = useMemo(() => {\n // Figma's Hover/Active state is overlay-mono laid over the resting fill,\n // not a swap to a different surface colour.\n const overlay = theme.colors.overlay.mono;\n\n // A disabled cell is not actionable, so it gets no pointer feedback.\n // Leaving these undefined (rather than `{}`) means Box's `&:hover` and\n // `&:active` blocks emit no declarations at all.\n const overlayState = disabled ? undefined : { backgroundColor: overlay };\n\n // The surface view already paints background-secondary, so its hover has\n // to stack overlay-mono ON TOP of that fill. A hover background-color\n // would replace it instead, so compose both layers with a flat\n // linear-gradient (same technique as Stepper's surface prop).\n const surfaceOverlayState = disabled\n ? undefined\n : {\n background: `linear-gradient(0deg, ${overlay} 0%, ${overlay} 100%), ${theme.colors.background.secondary}`,\n };\n\n switch (view) {\n case \"stroke\":\n return {\n borderRadius: theme.shape.cell.borderRadius,\n borderWidth: theme.shape.cell.borderWidth,\n borderColor: theme.colors.border.secondary,\n padding: CELL_PADDING,\n hoverStyle: overlayState,\n pressStyle: overlayState,\n };\n case \"surface\":\n return {\n backgroundColor: theme.colors.background.secondary,\n borderRadius: theme.shape.cell.borderRadius,\n padding: CELL_PADDING,\n hoverStyle: surfaceOverlayState,\n pressStyle: surfaceOverlayState,\n };\n default:\n return {\n minHeight: CELL_MIN_HEIGHT,\n hoverStyle: overlayState,\n pressStyle: overlayState,\n };\n }\n }, [view, theme, disabled]);\n\n const hasPress = !disabled && onPress != null;\n\n return (\n <Box\n testID={testID}\n ref={ref}\n alignItems=\"center\"\n width=\"100%\"\n flexDirection=\"row\"\n gap={CELL_GAP}\n // `disabled` is deliberately NOT forwarded to Box. Box maps it to\n // `opacity: 0.5` + `pointer-events: none`, which would dim the row and\n // make interactive children inside Cell.Slot (Radio, Button)\n // unclickable. Cell gates only its own affordances and leaves the\n // dimmed look to the consumer.\n onPress={disabled ? undefined : onPress}\n cursor={disabled ? \"not-allowed\" : hasPress ? \"pointer\" : undefined}\n aria-disabled={ariaDisabled ?? (disabled || undefined)}\n // View defaults first, consumer props second: `gap`, `minHeight` and\n // the padding props all stay overridable.\n {...viewStyles}\n {...props}\n style={{ color: theme.colors.content.primary, ...style }}\n >\n {children}\n </Box>\n );\n }\n);\n\nCellRoot.displayName = \"Cell\";\n\nconst CellSlot = forwardRef<any, CellSlotProps>(\n ({ children, testID, ...props }, ref) => {\n return (\n <Box\n testID={testID}\n ref={ref}\n alignItems=\"center\"\n justifyContent=\"center\"\n flexDirection=\"row\"\n {...props}\n style={{ flexShrink: 0, ...props.style }}\n >\n {children}\n </Box>\n );\n }\n);\n\nCellSlot.displayName = \"Cell.Slot\";\n\nconst CellContent = forwardRef<any, CellContentProps>(\n ({ children, testID, ...props }, ref) => {\n return (\n <Box\n testID={testID}\n ref={ref}\n flexDirection=\"column\"\n justifyContent=\"center\"\n {...props}\n style={{ flex: 1, ...props.style }}\n >\n {children}\n </Box>\n );\n }\n);\n\nCellContent.displayName = \"Cell.Content\";\n\n/**\n * Turns a typography token into Text props. `lineHeight` is converted to a\n * number so the same value works on web (px) and React Native.\n */\nconst resolveTextStyle = (\n productContext: Parameters<typeof getTypographyVariant>[0],\n variant: CellTextVariant\n): { fontSize?: number; lineHeight?: number; fontWeight?: string } => {\n const token = getTypographyVariant(productContext, variant);\n if (!token) return {};\n const lineHeight = parseFloat(String(token.lineHeight));\n return {\n fontSize: token.fontSize,\n lineHeight: Number.isNaN(lineHeight) ? undefined : lineHeight,\n fontWeight: String(token.fontWeight),\n };\n};\n\nconst CellTextRow = ({\n left,\n right,\n leftProps,\n rightProps,\n layout,\n sideGap,\n}: {\n left?: React.ReactNode;\n right?: React.ReactNode;\n leftProps?: Record<string, unknown>;\n rightProps?: Record<string, unknown>;\n layout: CellTextLayout;\n sideGap: number;\n}) => {\n if (!left && !right) return null;\n\n // \"equal\": both parts share the row 50/50 (historical behaviour).\n // \"fill-start\": the left part takes the remaining width and the right part\n // sizes to its content, so a long label does not wrap next to a short value.\n const leftFlex = { flex: 1, minWidth: 0, minHeight: 1 };\n const rightFlex =\n layout === \"fill-start\"\n ? { flexGrow: 0, flexShrink: 0, flexBasis: \"auto\", minHeight: 1 }\n : { flex: 1, minWidth: 0, minHeight: 1 };\n\n return (\n <Box\n flexDirection=\"row\"\n gap={sideGap}\n alignItems=\"center\"\n width=\"100%\"\n >\n {left != null && (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n gap={CELL_TEXT_ROW_GAP}\n style={leftFlex}\n >\n {typeof left === \"string\" ? <Text {...leftProps}>{left}</Text> : left}\n </Box>\n )}\n {right != null && (\n <Box\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"flex-end\"\n gap={CELL_TEXT_ROW_GAP}\n style={rightFlex}\n >\n {typeof right === \"string\" ? (\n <Text {...rightProps}>{right}</Text>\n ) : (\n right\n )}\n </Box>\n )}\n </Box>\n );\n};\n\nconst CellText = forwardRef<any, CellTextProps>(\n (\n {\n title,\n titleRight,\n description,\n descriptionRight,\n caption,\n captionRight,\n layout = \"equal\",\n sideGap = CELL_GAP,\n titleVariant = \"bodyMdAccent\",\n titleRightVariant = \"bodyXsParagraph\",\n descriptionVariant = \"bodyXsParagraph\",\n descriptionRightVariant = \"bodyXsParagraph\",\n captionVariant = \"bodyXsParagraph\",\n captionRightVariant = \"bodyXsParagraph\",\n testID,\n themeMode,\n themeProductContext,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const productContext = theme.productContext;\n\n const hasDescriptions = description != null || descriptionRight != null;\n const hasCaptions = caption != null || captionRight != null;\n\n const captionColor = theme.colors.content.tertiary;\n\n return (\n <Box\n testID={testID}\n ref={ref}\n flexDirection=\"column\"\n justifyContent=\"center\"\n gap={CELL_TEXT_ROW_GAP}\n {...props}\n style={{ flex: 1, minWidth: 0, minHeight: 1, ...props.style }}\n >\n <CellTextRow\n left={title}\n right={titleRight}\n layout={layout}\n sideGap={sideGap}\n leftProps={resolveTextStyle(productContext, titleVariant)}\n rightProps={resolveTextStyle(productContext, titleRightVariant)}\n />\n {hasDescriptions && (\n <CellTextRow\n left={description}\n right={descriptionRight}\n layout={layout}\n sideGap={sideGap}\n leftProps={resolveTextStyle(productContext, descriptionVariant)}\n rightProps={resolveTextStyle(\n productContext,\n descriptionRightVariant\n )}\n />\n )}\n {hasCaptions && (\n <CellTextRow\n left={caption}\n right={captionRight}\n layout={layout}\n sideGap={sideGap}\n leftProps={{\n ...resolveTextStyle(productContext, captionVariant),\n color: captionColor,\n }}\n rightProps={{\n ...resolveTextStyle(productContext, captionRightVariant),\n color: captionColor,\n }}\n />\n )}\n </Box>\n );\n }\n);\n\nCellText.displayName = \"Cell.Text\";\n\nexport const Cell = Object.assign(CellRoot, {\n Slot: CellSlot,\n Content: CellContent,\n Text: CellText,\n});\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"],"mappings":"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","names":["jsx","jsx"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xsolla/xui-cell",
3
- "version": "0.225.0",
3
+ "version": "0.226.0",
4
4
  "main": "./web/index.js",
5
5
  "module": "./web/index.mjs",
6
6
  "types": "./web/index.d.ts",
@@ -10,10 +10,10 @@
10
10
  "build:native": "PLATFORM=native tsup"
11
11
  },
12
12
  "dependencies": {
13
- "@xsolla/xui-avatar": "0.225.0",
14
- "@xsolla/xui-button": "0.225.0",
15
- "@xsolla/xui-core": "0.225.0",
16
- "@xsolla/xui-primitives-core": "0.225.0"
13
+ "@xsolla/xui-avatar": "0.226.0",
14
+ "@xsolla/xui-button": "0.226.0",
15
+ "@xsolla/xui-core": "0.226.0",
16
+ "@xsolla/xui-primitives-core": "0.226.0"
17
17
  },
18
18
  "peerDependencies": {
19
19
  "react": ">=16.8.0",
package/web/index.d.mts CHANGED
@@ -6,7 +6,15 @@ import { ThemeOverrideProps } from '@xsolla/xui-core';
6
6
  type CellView = "default" | "stroke" | "surface";
7
7
  interface CellProps extends BoxProps, ThemeOverrideProps {
8
8
  children?: ReactNode;
9
- /** Visual variant of the cell container. */
9
+ /**
10
+ * Visual variant of the cell container.
11
+ *
12
+ * Spacing defaults come from the spacing / control-size scales and can be
13
+ * overridden with the regular Box props, which are applied after the view
14
+ * defaults: `gap` (default 12, `spacing/150`), `minHeight` (default 56 on
15
+ * `default`, `control-size/650`), `padding` / `paddingVertical` /
16
+ * `paddingHorizontal` (default 8 on `stroke` and `surface`, `spacing/100`).
17
+ */
10
18
  view?: CellView;
11
19
  /**
12
20
  * @deprecated Use `view="stroke"` instead.
@@ -34,6 +42,20 @@ interface CellContentProps extends BoxProps {
34
42
  children?: ReactNode;
35
43
  testID?: string;
36
44
  }
45
+ /**
46
+ * How `Cell.Text` shares a row's width between its left and right parts.
47
+ *
48
+ * - `"equal"` — both parts get an equal share (50/50). Long left text wraps
49
+ * even when the right value is short. This is the historical behaviour.
50
+ * - `"fill-start"` — the left part takes the remaining width and the right
51
+ * part sizes to its content. Use it for label/value rows.
52
+ */
53
+ type CellTextLayout = "equal" | "fill-start";
54
+ /**
55
+ * Body typography token used by a `Cell.Text` slot. Resolved for the active
56
+ * product context via `getTypographyVariant` from `@xsolla/xui-core`.
57
+ */
58
+ type CellTextVariant = "bodyLg" | "bodyLgAccent" | "bodyLgParagraph" | "bodyMd" | "bodyMdAccent" | "bodyMdParagraph" | "bodySm" | "bodySmAccent" | "bodySmParagraph" | "bodyXs" | "bodyXsAccent" | "bodyXsParagraph" | "bodyXxs" | "bodyXxsAccent" | "bodyXxsParagraph";
37
59
  interface CellTextProps extends BoxProps, ThemeOverrideProps {
38
60
  /** Primary title on the left. */
39
61
  title?: ReactNode;
@@ -47,6 +69,34 @@ interface CellTextProps extends BoxProps, ThemeOverrideProps {
47
69
  caption?: ReactNode;
48
70
  /** Caption text on the right (third row, tertiary color). */
49
71
  captionRight?: ReactNode;
72
+ /**
73
+ * How each row splits its width between the left and right parts.
74
+ * @default "equal"
75
+ */
76
+ layout?: CellTextLayout;
77
+ /**
78
+ * Horizontal gap in px between the left and right parts of each row.
79
+ * The vertical gap between rows is the regular `gap` prop (default 2,
80
+ * `spacing/25`).
81
+ * @default 12
82
+ */
83
+ sideGap?: number;
84
+ /**
85
+ * Typography token for a string `title`. Applies only to string values;
86
+ * a ReactNode is rendered as-is.
87
+ * @default "bodyMdAccent"
88
+ */
89
+ titleVariant?: CellTextVariant;
90
+ /** Typography token for a string `titleRight`. @default "bodyXsParagraph" */
91
+ titleRightVariant?: CellTextVariant;
92
+ /** Typography token for a string `description`. @default "bodyXsParagraph" */
93
+ descriptionVariant?: CellTextVariant;
94
+ /** Typography token for a string `descriptionRight`. @default "bodyXsParagraph" */
95
+ descriptionRightVariant?: CellTextVariant;
96
+ /** Typography token for a string `caption`. @default "bodyXsParagraph" */
97
+ captionVariant?: CellTextVariant;
98
+ /** Typography token for a string `captionRight`. @default "bodyXsParagraph" */
99
+ captionRightVariant?: CellTextVariant;
50
100
  testID?: string;
51
101
  }
52
102
 
@@ -56,4 +106,4 @@ declare const Cell: react.ForwardRefExoticComponent<CellProps & react.RefAttribu
56
106
  Text: react.ForwardRefExoticComponent<CellTextProps & react.RefAttributes<any>>;
57
107
  };
58
108
 
59
- export { Cell, type CellContentProps, type CellProps, type CellSlotProps, type CellTextProps, type CellView };
109
+ export { Cell, type CellContentProps, type CellProps, type CellSlotProps, type CellTextLayout, type CellTextProps, type CellTextVariant, type CellView };
package/web/index.d.ts CHANGED
@@ -6,7 +6,15 @@ import { ThemeOverrideProps } from '@xsolla/xui-core';
6
6
  type CellView = "default" | "stroke" | "surface";
7
7
  interface CellProps extends BoxProps, ThemeOverrideProps {
8
8
  children?: ReactNode;
9
- /** Visual variant of the cell container. */
9
+ /**
10
+ * Visual variant of the cell container.
11
+ *
12
+ * Spacing defaults come from the spacing / control-size scales and can be
13
+ * overridden with the regular Box props, which are applied after the view
14
+ * defaults: `gap` (default 12, `spacing/150`), `minHeight` (default 56 on
15
+ * `default`, `control-size/650`), `padding` / `paddingVertical` /
16
+ * `paddingHorizontal` (default 8 on `stroke` and `surface`, `spacing/100`).
17
+ */
10
18
  view?: CellView;
11
19
  /**
12
20
  * @deprecated Use `view="stroke"` instead.
@@ -34,6 +42,20 @@ interface CellContentProps extends BoxProps {
34
42
  children?: ReactNode;
35
43
  testID?: string;
36
44
  }
45
+ /**
46
+ * How `Cell.Text` shares a row's width between its left and right parts.
47
+ *
48
+ * - `"equal"` — both parts get an equal share (50/50). Long left text wraps
49
+ * even when the right value is short. This is the historical behaviour.
50
+ * - `"fill-start"` — the left part takes the remaining width and the right
51
+ * part sizes to its content. Use it for label/value rows.
52
+ */
53
+ type CellTextLayout = "equal" | "fill-start";
54
+ /**
55
+ * Body typography token used by a `Cell.Text` slot. Resolved for the active
56
+ * product context via `getTypographyVariant` from `@xsolla/xui-core`.
57
+ */
58
+ type CellTextVariant = "bodyLg" | "bodyLgAccent" | "bodyLgParagraph" | "bodyMd" | "bodyMdAccent" | "bodyMdParagraph" | "bodySm" | "bodySmAccent" | "bodySmParagraph" | "bodyXs" | "bodyXsAccent" | "bodyXsParagraph" | "bodyXxs" | "bodyXxsAccent" | "bodyXxsParagraph";
37
59
  interface CellTextProps extends BoxProps, ThemeOverrideProps {
38
60
  /** Primary title on the left. */
39
61
  title?: ReactNode;
@@ -47,6 +69,34 @@ interface CellTextProps extends BoxProps, ThemeOverrideProps {
47
69
  caption?: ReactNode;
48
70
  /** Caption text on the right (third row, tertiary color). */
49
71
  captionRight?: ReactNode;
72
+ /**
73
+ * How each row splits its width between the left and right parts.
74
+ * @default "equal"
75
+ */
76
+ layout?: CellTextLayout;
77
+ /**
78
+ * Horizontal gap in px between the left and right parts of each row.
79
+ * The vertical gap between rows is the regular `gap` prop (default 2,
80
+ * `spacing/25`).
81
+ * @default 12
82
+ */
83
+ sideGap?: number;
84
+ /**
85
+ * Typography token for a string `title`. Applies only to string values;
86
+ * a ReactNode is rendered as-is.
87
+ * @default "bodyMdAccent"
88
+ */
89
+ titleVariant?: CellTextVariant;
90
+ /** Typography token for a string `titleRight`. @default "bodyXsParagraph" */
91
+ titleRightVariant?: CellTextVariant;
92
+ /** Typography token for a string `description`. @default "bodyXsParagraph" */
93
+ descriptionVariant?: CellTextVariant;
94
+ /** Typography token for a string `descriptionRight`. @default "bodyXsParagraph" */
95
+ descriptionRightVariant?: CellTextVariant;
96
+ /** Typography token for a string `caption`. @default "bodyXsParagraph" */
97
+ captionVariant?: CellTextVariant;
98
+ /** Typography token for a string `captionRight`. @default "bodyXsParagraph" */
99
+ captionRightVariant?: CellTextVariant;
50
100
  testID?: string;
51
101
  }
52
102
 
@@ -56,4 +106,4 @@ declare const Cell: react.ForwardRefExoticComponent<CellProps & react.RefAttribu
56
106
  Text: react.ForwardRefExoticComponent<CellTextProps & react.RefAttributes<any>>;
57
107
  };
58
108
 
59
- export { Cell, type CellContentProps, type CellProps, type CellSlotProps, type CellTextProps, type CellView };
109
+ export { Cell, type CellContentProps, type CellProps, type CellSlotProps, type CellTextLayout, type CellTextProps, type CellTextVariant, type CellView };