@xsolla/xui-table 0.207.0 → 0.208.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 +155 -17
- package/native/index.d.mts +84 -5
- package/native/index.d.ts +84 -5
- package/native/index.js +111 -7
- package/native/index.js.map +1 -1
- package/native/index.mjs +111 -7
- package/native/index.mjs.map +1 -1
- package/package.json +4 -4
- package/web/index.d.mts +84 -5
- package/web/index.d.ts +84 -5
- package/web/index.js +111 -7
- package/web/index.js.map +1 -1
- package/web/index.mjs +111 -7
- package/web/index.mjs.map +1 -1
package/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.tsx","../../src/Table.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx"],"sourcesContent":["export * from \"./Table\";\nexport * from \"./types\";\n","import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, isNative } from \"@xsolla/xui-core\";\nimport { Sort } from \"@xsolla/xui-icons-base\";\nimport {\n TableBodyProps,\n TableCaptionProps,\n TableCellProps,\n TableFooterProps,\n TableHeaderProps,\n TableHeadProps,\n TableProps,\n TableRowProps,\n} from \"./types\";\n\n/**\n * Tracks which rowgroup the current <Table.Row> sits inside, so the row can\n * pick the right sizing (header rows are slightly taller / styled\n * differently per `theme.sizing.table`).\n */\ntype RowGroup = \"header\" | \"body\";\nconst TableRowGroupContext = createContext<RowGroup>(\"body\");\n\n/**\n * Tracks whether the parent <Table.Row> is hovered or has focus inside it.\n * Cells that opt into `revealOnHover` read this to decide whether to show\n * their content. Defaults to `true` so cells used outside a row (e.g. inside\n * <Table.Header>) are always visible.\n */\nconst RowRevealContext = createContext<{ revealed: boolean }>({\n revealed: true,\n});\n\n/**\n * Detects whether the device is hover-capable (desktop) vs touch-only (mobile).\n * On touch-only devices we always reveal action cells so they can be tapped —\n * matching the Figma spec (\"Right cell actions ... always visible on touch\n * devices\"). SSR-safe: returns `true` until mounted, which means actions stay\n * revealed on the server (no flash-of-hidden-actions on first paint).\n *\n * Table is web-only for now — on native this hook short-circuits and never\n * runs the media query.\n */\nconst useHoverCapable = (): boolean => {\n const [hoverCapable, setHoverCapable] = useState(true);\n useEffect(() => {\n if (isNative) return;\n if (typeof window === \"undefined\" || !window.matchMedia) return;\n const mq = window.matchMedia(\"(hover: hover)\");\n setHoverCapable(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setHoverCapable(e.matches);\n mq.addEventListener?.(\"change\", onChange);\n return () => mq.removeEventListener?.(\"change\", onChange);\n }, []);\n return hoverCapable;\n};\n\nconst Divider: React.FC<{ color: string }> = ({ color }) => (\n <Box\n width=\"100%\"\n height={1}\n backgroundColor={color}\n style={{ flexShrink: 0 }}\n />\n);\n\nconst TableRoot = forwardRef<any, TableProps>(\n ({ children, testID, themeMode, themeProductContext }, ref) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n return (\n <Box\n ref={ref}\n testID={testID}\n flexDirection=\"column\"\n alignItems=\"stretch\"\n gap={sizing.containerGap}\n paddingVertical={sizing.containerPaddingVertical}\n backgroundColor={theme.colors.background.primary}\n borderRadius={sizing.containerRadius}\n width=\"100%\"\n role=\"table\"\n style={{\n color: theme.colors.content.primary,\n overflow: \"clip\",\n }}\n >\n {children}\n </Box>\n );\n }\n);\n\nTableRoot.displayName = \"Table\";\n\nconst TableCaption = forwardRef<any, TableCaptionProps>(\n ({ children, themeMode, themeProductContext, style, ...props }, ref) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingHorizontal={sizing.headerRowPaddingHorizontal}\n width=\"100%\"\n // <caption> isn't a valid ARIA role; consumers can pass role=\"region\"\n // + aria-label via ...props if they want it announced.\n {...props}\n style={style}\n >\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Text\n fontSize={sizing.captionFontSize}\n lineHeight={sizing.captionLineHeight}\n color={theme.colors.content.secondary}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </Box>\n );\n }\n);\n\nTableCaption.displayName = \"Table.Caption\";\n\nconst TableHeader = forwardRef<any, TableHeaderProps>(\n ({ children, themeMode, themeProductContext, style, ...props }, ref) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n return (\n <TableRowGroupContext.Provider value=\"header\">\n <Box\n ref={ref}\n flexDirection=\"column\"\n alignItems=\"stretch\"\n width=\"100%\"\n role=\"rowgroup\"\n {...props}\n style={{\n position: \"sticky\",\n top: 0,\n zIndex: 1,\n backgroundColor: theme.colors.background.primary,\n ...style,\n }}\n >\n {children}\n <Divider color={theme.colors.border.secondary} />\n </Box>\n </TableRowGroupContext.Provider>\n );\n }\n);\n\nTableHeader.displayName = \"Table.Header\";\n\nconst TableBody = forwardRef<any, TableBodyProps>(\n (\n { children, style, minRows, themeMode, themeProductContext, ...props },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n // Each row paints a 1px divider after it (rendered as a sibling Box\n // inside Table.Row), except the very last row in the body which\n // hides its divider. So a fully filled body of N rows is\n // `N × rowHeight + (N - 1) × 1px`.\n const DIVIDER_HEIGHT = 1;\n const computedMinHeight = minRows\n ? minRows * sizing.rowHeight + (minRows - 1) * DIVIDER_HEIGHT\n : undefined;\n\n // Decide whether to auto-pad with placeholder slots. We only pad\n // when every direct child is a <Table.Row>; consumers using a\n // single non-row block (e.g. a custom \"no results\" panel) get just\n // the reserved min-height so they can stretch their content to fill.\n let renderedChildren: ReactNode = children;\n if (minRows) {\n const childArray = React.Children.toArray(children);\n const hasOnlyRowChildren =\n childArray.length > 0 &&\n childArray.every((c) => React.isValidElement(c) && c.type === TableRow);\n const realRowCount = hasOnlyRowChildren ? childArray.length : 0;\n const placeholderCount = hasOnlyRowChildren\n ? Math.max(0, minRows - realRowCount)\n : 0;\n\n if (placeholderCount > 0) {\n // Override the last real row's `hideDivider` so the body always\n // ends with a divider-less slot — matching how a full page hides\n // the last row's divider.\n const patchedRows = childArray.map((child, i) => {\n if (!React.isValidElement(child)) return child;\n const isLastRealRow = i === realRowCount - 1;\n return React.cloneElement(child, {\n hideDivider: isLastRealRow\n ? false\n : (child.props as any).hideDivider,\n } as any);\n });\n\n const placeholders = Array.from({ length: placeholderCount }).map(\n (_, i) => {\n const isLast = i === placeholderCount - 1;\n return (\n <Box\n key={`__table-body-placeholder-${i}`}\n aria-hidden\n style={{\n height: isLast\n ? sizing.rowHeight\n : sizing.rowHeight + DIVIDER_HEIGHT,\n flexShrink: 0,\n }}\n />\n );\n }\n );\n\n renderedChildren = (\n <>\n {patchedRows}\n {placeholders}\n </>\n );\n }\n }\n\n return (\n <TableRowGroupContext.Provider value=\"body\">\n <Box\n ref={ref}\n flexDirection=\"column\"\n alignItems=\"stretch\"\n width=\"100%\"\n role=\"rowgroup\"\n {...props}\n style={{\n ...(computedMinHeight !== undefined && {\n minHeight: computedMinHeight,\n }),\n ...style,\n }}\n >\n {renderedChildren}\n </Box>\n </TableRowGroupContext.Provider>\n );\n }\n);\n\nTableBody.displayName = \"Table.Body\";\n\nconst TableRow = forwardRef<any, TableRowProps>(\n (\n {\n children,\n hoverable: hoverableProp,\n selected,\n hideDivider: hideDividerProp,\n onPress,\n testID,\n themeMode,\n themeProductContext,\n style,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n onKeyDown,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n const rowGroup = useContext(TableRowGroupContext);\n const hoverCapable = useHoverCapable();\n\n const isHeaderRow = rowGroup === \"header\";\n\n // Header rows are not hoverable by default and don't render a divider\n // (Header already paints its own top/bottom dividers).\n const hoverable = hoverableProp ?? !isHeaderRow;\n const hideDivider = hideDividerProp ?? isHeaderRow;\n\n // Track hover + focus-within so descendant <Table.Cell revealOnHover>\n // cells can decide whether to show themselves. Single re-render per\n // hover/focus change, scoped to this row only.\n const [hovered, setHovered] = useState(false);\n const [focusedWithin, setFocusedWithin] = useState(false);\n\n // On touch-only devices the reveal logic short-circuits to \"always\n // visible\" — matches the Figma spec.\n const revealed = hoverCapable ? hovered || focusedWithin : true;\n\n const handleMouseEnter = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setHovered(true);\n onMouseEnter?.(e);\n },\n [onMouseEnter]\n );\n const handleMouseLeave = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setHovered(false);\n onMouseLeave?.(e);\n },\n [onMouseLeave]\n );\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLElement>) => {\n setFocusedWithin(true);\n onFocus?.(e);\n },\n [onFocus]\n );\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLElement>) => {\n // When focus moves between two children of this row the blur fires\n // here but the row is still focus-within — keep the state truthy.\n if (\n e.relatedTarget instanceof Node &&\n e.currentTarget.contains(e.relatedTarget)\n ) {\n onBlur?.(e);\n return;\n }\n setFocusedWithin(false);\n onBlur?.(e);\n },\n [onBlur]\n );\n\n // Rows opt into keyboard activation only when they are interactive\n // (i.e. consumer passed `onPress`). Enter/Space mirror native button\n // behavior; Space is preventDefault'd so the page doesn't scroll.\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<Element>) => {\n onKeyDown?.(e);\n if (!onPress || e.defaultPrevented) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPress();\n }\n },\n [onKeyDown, onPress]\n );\n\n const baseBg = selected\n ? theme.colors.background.secondary\n : theme.colors.background.primary;\n\n const rowHeight = isHeaderRow ? sizing.headerRowHeight : sizing.rowHeight;\n const rowPaddingHorizontal = isHeaderRow\n ? sizing.headerRowPaddingHorizontal\n : sizing.rowPaddingHorizontal;\n\n const ctxValue = useMemo(() => ({ revealed }), [revealed]);\n\n return (\n <RowRevealContext.Provider value={ctxValue}>\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n height={rowHeight}\n paddingHorizontal={rowPaddingHorizontal}\n width=\"100%\"\n gap={sizing.cellGap}\n backgroundColor={baseBg}\n cursor={onPress ? \"pointer\" : undefined}\n hoverStyle={\n hoverable\n ? { backgroundColor: theme.colors.background.secondary }\n : undefined\n }\n onPress={onPress}\n role=\"row\"\n tabIndex={onPress ? 0 : undefined}\n aria-selected={selected || undefined}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n onKeyDown={handleKeyDown}\n style={style}\n >\n {children}\n </Box>\n {!hideDivider && <Divider color={theme.colors.border.secondary} />}\n </RowRevealContext.Provider>\n );\n }\n);\n\nTableRow.displayName = \"Table.Row\";\n\nconst positionToFlex = (position: TableCellProps[\"position\"]) => {\n switch (position) {\n case \"left\":\n return { flexShrink: 0 };\n case \"right\":\n return { flexShrink: 0, marginLeft: \"auto\" };\n default:\n return {};\n }\n};\n\nconst alignToJustify = (align: TableCellProps[\"align\"]) => {\n switch (align) {\n case \"right\":\n return \"flex-end\" as const;\n case \"center\":\n return \"center\" as const;\n default:\n return \"flex-start\" as const;\n }\n};\n\nconst TableCell = forwardRef<any, TableCellProps>(\n (\n {\n children,\n align = \"left\",\n position = \"default\",\n width,\n grow,\n revealOnHover,\n testID,\n themeMode,\n themeProductContext,\n style,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n const { revealed } = useContext(RowRevealContext);\n\n const positionStyle = useMemo(() => positionToFlex(position), [position]);\n\n // Per Figma spec: hide via opacity + pointer-events (NOT visibility) so\n // keyboard Tab still focuses the descendants. Focusing a descendant flips\n // `revealed` to true via RowRevealContext, restoring pointer-events.\n const revealStyle: React.CSSProperties =\n revealOnHover && !revealed\n ? { opacity: 0, pointerEvents: \"none\" }\n : revealOnHover\n ? { opacity: 1, transition: \"opacity 0.15s ease\" }\n : {};\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={alignToJustify(align)}\n gap={8}\n height=\"100%\"\n width={width}\n role=\"cell\"\n {...props}\n style={{\n flex: width != null ? \"0 0 auto\" : (grow ?? 1),\n minWidth: 0,\n ...positionStyle,\n ...revealStyle,\n ...style,\n }}\n >\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Text\n fontSize={sizing.cellFontSize}\n lineHeight={sizing.cellLineHeight}\n color={theme.colors.content.primary}\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n maxWidth: \"100%\",\n }}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </Box>\n );\n }\n);\n\nTableCell.displayName = \"Table.Cell\";\n\n/**\n * Sort indicator. Uses the `Sort` line icon from `@xsolla/xui-icons-base`\n * (matches the Figma spec — a stacked up/down chevron). The icon is the\n * same in all three states; opacity differentiates \"sortable but not\n * active\" (`none`, 40%) from \"active sort\" (`ascending` / `descending`,\n * 100%). Direction is communicated to assistive tech via `aria-sort` on\n * the parent <Table.Head>.\n */\nconst SortIcon: React.FC<{\n direction: \"ascending\" | \"descending\" | \"none\";\n color: string;\n size: number;\n}> = ({ direction, color, size }) => (\n <Box\n style={{\n flexShrink: 0,\n opacity: direction === \"none\" ? 0.4 : 1,\n transition: \"opacity 0.15s ease\",\n }}\n >\n <Sort variant=\"line\" size={size} color={color} aria-hidden />\n </Box>\n);\n\nconst TableHead = forwardRef<any, TableHeadProps>(\n (\n {\n children,\n align = \"left\",\n position = \"default\",\n width,\n grow,\n sort,\n onSortToggle,\n testID,\n themeMode,\n themeProductContext,\n style,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n const positionStyle = useMemo(() => positionToFlex(position), [position]);\n const sortable = sort != null;\n\n const ariaSort: \"ascending\" | \"descending\" | \"none\" | undefined = sortable\n ? sort\n : undefined;\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={alignToJustify(align)}\n gap={sizing.headerCellGap}\n height=\"100%\"\n width={width}\n role=\"columnheader\"\n aria-sort={ariaSort}\n cursor={sortable ? \"pointer\" : undefined}\n onPress={sortable ? onSortToggle : undefined}\n {...props}\n style={{\n flex: width != null ? \"0 0 auto\" : (grow ?? 1),\n minWidth: 0,\n ...positionStyle,\n ...style,\n }}\n >\n {sortable && (\n <SortIcon\n direction={sort}\n color={theme.colors.content.secondary}\n size={sizing.headerCellFontSize + 2}\n />\n )}\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Text\n fontSize={sizing.headerCellFontSize}\n lineHeight={sizing.headerCellLineHeight}\n color={theme.colors.content.secondary}\n fontWeight=\"500\"\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </Box>\n );\n }\n);\n\nTableHead.displayName = \"Table.Head\";\n\nconst TableFooter = forwardRef<any, TableFooterProps>(\n ({ children, style, ...props }, ref) => {\n const { theme } = useResolvedTheme();\n const sizing = theme.sizing.table;\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={sizing.paginationGap}\n paddingHorizontal={sizing.paginationPaddingHorizontal}\n width=\"100%\"\n {...props}\n style={style}\n >\n {children}\n </Box>\n );\n }\n);\n\nTableFooter.displayName = \"Table.Footer\";\n\nexport const Table = Object.assign(TableRoot, {\n Caption: TableCaption,\n Header: TableHeader,\n Body: TableBody,\n Footer: TableFooter,\n Row: TableRow,\n Head: TableHead,\n Cell: TableCell,\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\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 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 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":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime","React"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.tsx","../../src/Table.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx"],"sourcesContent":["export * from \"./Table\";\nexport * from \"./types\";\n","import React, {\n createContext,\n forwardRef,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useState,\n type ReactNode,\n} from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, isNative } from \"@xsolla/xui-core\";\nimport { Sort } from \"@xsolla/xui-icons-base\";\nimport {\n TableBodyProps,\n TableCaptionProps,\n TableCellProps,\n TableDevice,\n TableFloatingCellConfig,\n TableFooterProps,\n TableHeaderProps,\n TableHeadProps,\n TableProps,\n TableRowProps,\n} from \"./types\";\n\n/**\n * Tracks which rowgroup the current <Table.Row> sits inside, so the row can\n * pick the right sizing (header rows are slightly taller / styled\n * differently per `theme.sizing.table`).\n */\ntype RowGroup = \"header\" | \"body\";\nconst TableRowGroupContext = createContext<RowGroup>(\"body\");\n\n/**\n * Layout switches set on <Table> and consumed further down the tree:\n * <Table.Row> reads `device` to decide whether `revealOnHover` cells are\n * always visible, and `floatFirstColumn` to decide whether to pin its\n * first cell.\n */\ninterface TableConfig {\n device: TableDevice;\n floatFirstColumn: boolean;\n}\nconst TableConfigContext = createContext<TableConfig>({\n device: \"desktop\",\n floatFirstColumn: false,\n});\n\n/**\n * Tracks whether the parent <Table.Row> is hovered or has focus inside it.\n * Cells that opt into `revealOnHover` read this to decide whether to show\n * their content. Defaults to `true` so cells used outside a row (e.g. inside\n * <Table.Header>) are always visible.\n */\nconst RowRevealContext = createContext<{ revealed: boolean }>({\n revealed: true,\n});\n\n/**\n * Detects whether the device is hover-capable (desktop) vs touch-only (mobile).\n * On touch-only devices we always reveal action cells so they can be tapped —\n * matching the Figma spec (\"Right cell actions ... always visible on touch\n * devices\"). SSR-safe: returns `true` until mounted, which means actions stay\n * revealed on the server (no flash-of-hidden-actions on first paint).\n *\n * Table is web-only for now — on native this hook short-circuits and never\n * runs the media query.\n */\nconst useHoverCapable = (): boolean => {\n const [hoverCapable, setHoverCapable] = useState(true);\n useEffect(() => {\n if (isNative) return;\n if (typeof window === \"undefined\" || !window.matchMedia) return;\n const mq = window.matchMedia(\"(hover: hover)\");\n setHoverCapable(mq.matches);\n const onChange = (e: MediaQueryListEvent) => setHoverCapable(e.matches);\n mq.addEventListener?.(\"change\", onChange);\n return () => mq.removeEventListener?.(\"change\", onChange);\n }, []);\n return hoverCapable;\n};\n\nconst Divider: React.FC<{ color: string }> = ({ color }) => (\n <Box\n width=\"100%\"\n height={1}\n backgroundColor={color}\n style={{ flexShrink: 0 }}\n />\n);\n\n/**\n * Sticky-column styling for the pinned first cell. Applied to the real\n * first cell inside the horizontally scrolling container — deliberately\n * NOT a duplicate overlay, so there is no second copy to keep in step\n * with the real column.\n */\nconst floatingCellStyle = (\n floating: TableFloatingCellConfig\n): React.CSSProperties => ({\n position: \"sticky\",\n left: 0,\n zIndex: 2,\n backgroundColor: floating.background,\n paddingLeft: floating.paddingLeft,\n boxShadow: floating.shadow,\n});\n\nconst TableRoot = forwardRef<any, TableProps>(\n (\n {\n children,\n device = \"desktop\",\n scroll,\n scrollBar = false,\n floatFirstColumn = false,\n testID,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n // Pinning a column is a desktop-scroll feature. On mobile, horizontal\n // scrolling is already the reading mode, so readability is handled\n // through column order instead.\n const floatEnabled = floatFirstColumn && device !== \"mobile\";\n\n // Mobile scrolls by default; desktop opts in (or is opted in by\n // `floatFirstColumn`, which is meaningless without a scroll viewport).\n const scrollEnabled = scroll ?? (device === \"mobile\" || floatEnabled);\n\n const config = useMemo<TableConfig>(\n () => ({ device, floatFirstColumn: floatEnabled }),\n [device, floatEnabled]\n );\n\n const content = scrollEnabled\n ? wrapRowGroupsInScrollViewport(children, scrollBar)\n : children;\n\n return (\n <TableConfigContext.Provider value={config}>\n <Box\n ref={ref}\n testID={testID}\n flexDirection=\"column\"\n alignItems=\"stretch\"\n gap={sizing.containerGap}\n paddingVertical={sizing.containerPaddingVertical}\n backgroundColor={theme.colors.background.primary}\n borderRadius={sizing.containerRadius}\n width=\"100%\"\n role=\"table\"\n style={{\n color: theme.colors.content.primary,\n overflow: \"clip\",\n }}\n >\n {content}\n </Box>\n </TableConfigContext.Provider>\n );\n }\n);\n\nTableRoot.displayName = \"Table\";\n\nconst TableCaption = forwardRef<any, TableCaptionProps>(\n ({ children, themeMode, themeProductContext, style, ...props }, ref) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n paddingHorizontal={sizing.headerRowPaddingHorizontal}\n width=\"100%\"\n // <caption> isn't a valid ARIA role; consumers can pass role=\"region\"\n // + aria-label via ...props if they want it announced.\n {...props}\n style={style}\n >\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Text\n fontSize={sizing.captionFontSize}\n lineHeight={sizing.captionLineHeight}\n color={theme.colors.content.secondary}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </Box>\n );\n }\n);\n\nTableCaption.displayName = \"Table.Caption\";\n\nconst TableHeader = forwardRef<any, TableHeaderProps>(\n ({ children, themeMode, themeProductContext, style, ...props }, ref) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n return (\n <TableRowGroupContext.Provider value=\"header\">\n <Box\n ref={ref}\n flexDirection=\"column\"\n alignItems=\"stretch\"\n width=\"100%\"\n role=\"rowgroup\"\n {...props}\n style={{\n position: \"sticky\",\n top: 0,\n zIndex: 1,\n backgroundColor: theme.colors.background.primary,\n ...style,\n }}\n >\n {children}\n <Divider color={theme.colors.border.secondary} />\n </Box>\n </TableRowGroupContext.Provider>\n );\n }\n);\n\nTableHeader.displayName = \"Table.Header\";\n\nconst TableBody = forwardRef<any, TableBodyProps>(\n (\n { children, style, minRows, themeMode, themeProductContext, ...props },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n // Each row paints a 1px divider after it (rendered as a sibling Box\n // inside Table.Row), except the very last row in the body which\n // hides its divider. So a fully filled body of N rows is\n // `N × rowHeight + (N - 1) × 1px`.\n const DIVIDER_HEIGHT = 1;\n const computedMinHeight = minRows\n ? minRows * sizing.rowHeight + (minRows - 1) * DIVIDER_HEIGHT\n : undefined;\n\n // Decide whether to auto-pad with placeholder slots. We only pad\n // when every direct child is a <Table.Row>; consumers using a\n // single non-row block (e.g. a custom \"no results\" panel) get just\n // the reserved min-height so they can stretch their content to fill.\n let renderedChildren: ReactNode = children;\n if (minRows) {\n const childArray = React.Children.toArray(children);\n const hasOnlyRowChildren =\n childArray.length > 0 &&\n childArray.every((c) => React.isValidElement(c) && c.type === TableRow);\n const realRowCount = hasOnlyRowChildren ? childArray.length : 0;\n const placeholderCount = hasOnlyRowChildren\n ? Math.max(0, minRows - realRowCount)\n : 0;\n\n if (placeholderCount > 0) {\n // Override the last real row's `hideDivider` so the body always\n // ends with a divider-less slot — matching how a full page hides\n // the last row's divider.\n const patchedRows = childArray.map((child, i) => {\n if (!React.isValidElement(child)) return child;\n const isLastRealRow = i === realRowCount - 1;\n return React.cloneElement(child, {\n hideDivider: isLastRealRow\n ? false\n : (child.props as any).hideDivider,\n } as any);\n });\n\n const placeholders = Array.from({ length: placeholderCount }).map(\n (_, i) => {\n const isLast = i === placeholderCount - 1;\n return (\n <Box\n key={`__table-body-placeholder-${i}`}\n aria-hidden\n style={{\n height: isLast\n ? sizing.rowHeight\n : sizing.rowHeight + DIVIDER_HEIGHT,\n flexShrink: 0,\n }}\n />\n );\n }\n );\n\n renderedChildren = (\n <>\n {patchedRows}\n {placeholders}\n </>\n );\n }\n }\n\n return (\n <TableRowGroupContext.Provider value=\"body\">\n <Box\n ref={ref}\n flexDirection=\"column\"\n alignItems=\"stretch\"\n width=\"100%\"\n role=\"rowgroup\"\n {...props}\n style={{\n ...(computedMinHeight !== undefined && {\n minHeight: computedMinHeight,\n }),\n ...style,\n }}\n >\n {renderedChildren}\n </Box>\n </TableRowGroupContext.Provider>\n );\n }\n);\n\nTableBody.displayName = \"Table.Body\";\n\nconst TableRow = forwardRef<any, TableRowProps>(\n (\n {\n children,\n hoverable: hoverableProp,\n selected,\n hideDivider: hideDividerProp,\n onPress,\n testID,\n themeMode,\n themeProductContext,\n style,\n onMouseEnter,\n onMouseLeave,\n onFocus,\n onBlur,\n onKeyDown,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n const rowGroup = useContext(TableRowGroupContext);\n const { device, floatFirstColumn } = useContext(TableConfigContext);\n const hoverCapable = useHoverCapable();\n\n const isHeaderRow = rowGroup === \"header\";\n\n // Header rows are not hoverable by default and don't render a divider\n // (Header already paints its own top/bottom dividers).\n const hoverable = hoverableProp ?? !isHeaderRow;\n const hideDivider = hideDividerProp ?? isHeaderRow;\n\n // Track hover + focus-within so descendant <Table.Cell revealOnHover>\n // cells can decide whether to show themselves. Single re-render per\n // hover/focus change, scoped to this row only.\n const [hovered, setHovered] = useState(false);\n const [focusedWithin, setFocusedWithin] = useState(false);\n\n // On touch-only devices — and whenever the table is explicitly laid out\n // for mobile — the reveal logic short-circuits to \"always visible\", so\n // row actions stay tappable. Matches the Figma spec.\n const revealed =\n device === \"mobile\" || !hoverCapable ? true : hovered || focusedWithin;\n\n const handleMouseEnter = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setHovered(true);\n onMouseEnter?.(e);\n },\n [onMouseEnter]\n );\n const handleMouseLeave = useCallback(\n (e: React.MouseEvent<HTMLElement>) => {\n setHovered(false);\n onMouseLeave?.(e);\n },\n [onMouseLeave]\n );\n const handleFocus = useCallback(\n (e: React.FocusEvent<HTMLElement>) => {\n setFocusedWithin(true);\n onFocus?.(e);\n },\n [onFocus]\n );\n const handleBlur = useCallback(\n (e: React.FocusEvent<HTMLElement>) => {\n // When focus moves between two children of this row the blur fires\n // here but the row is still focus-within — keep the state truthy.\n if (\n e.relatedTarget instanceof Node &&\n e.currentTarget.contains(e.relatedTarget)\n ) {\n onBlur?.(e);\n return;\n }\n setFocusedWithin(false);\n onBlur?.(e);\n },\n [onBlur]\n );\n\n // Rows opt into keyboard activation only when they are interactive\n // (i.e. consumer passed `onPress`). Enter/Space mirror native button\n // behavior; Space is preventDefault'd so the page doesn't scroll.\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent<Element>) => {\n onKeyDown?.(e);\n if (!onPress || e.defaultPrevented) return;\n if (e.key === \"Enter\" || e.key === \" \") {\n e.preventDefault();\n onPress();\n }\n },\n [onKeyDown, onPress]\n );\n\n const baseBg = selected\n ? theme.colors.background.secondary\n : theme.colors.background.primary;\n\n const rowHeight = isHeaderRow ? sizing.headerRowHeight : sizing.rowHeight;\n const rowPaddingHorizontal = isHeaderRow\n ? sizing.headerRowPaddingHorizontal\n : sizing.rowPaddingHorizontal;\n\n const ctxValue = useMemo(() => ({ revealed }), [revealed]);\n\n // The pinned cell needs an opaque background of its own, otherwise the\n // scrolled-under columns show through it. `hoverStyle` lives on the row\n // Box, so mirror the resolved hover colour here.\n const resolvedBg =\n hoverable && hovered ? theme.colors.background.secondary : baseBg;\n\n // Hand the sticky treatment to the row's first cell. Only Table.Cell /\n // Table.Head are patched — an arbitrary consumer wrapper is left alone\n // so `__floating` can never leak onto the DOM.\n let renderedChildren: ReactNode = children;\n let didFloat = false;\n if (floatFirstColumn) {\n const childArray = React.Children.toArray(children);\n const firstCellIndex = childArray.findIndex(\n (c) =>\n React.isValidElement(c) &&\n (c.type === TableCell || c.type === TableHead)\n );\n\n if (firstCellIndex !== -1) {\n didFloat = true;\n const floating: TableFloatingCellConfig = {\n background: resolvedBg,\n paddingLeft: rowPaddingHorizontal,\n shadow: theme.shadow.surface,\n };\n renderedChildren = childArray.map((child, i) =>\n i === firstCellIndex && React.isValidElement(child)\n ? React.cloneElement(child, { __floating: floating } as any)\n : child\n );\n }\n }\n\n return (\n <RowRevealContext.Provider value={ctxValue}>\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n height={rowHeight}\n paddingHorizontal={rowPaddingHorizontal}\n width=\"100%\"\n gap={sizing.cellGap}\n backgroundColor={baseBg}\n cursor={onPress ? \"pointer\" : undefined}\n hoverStyle={\n hoverable\n ? { backgroundColor: theme.colors.background.secondary }\n : undefined\n }\n onPress={onPress}\n role=\"row\"\n tabIndex={onPress ? 0 : undefined}\n aria-selected={selected || undefined}\n onMouseEnter={handleMouseEnter}\n onMouseLeave={handleMouseLeave}\n onFocus={handleFocus}\n onBlur={handleBlur}\n {...props}\n onKeyDown={handleKeyDown}\n style={{\n // The pinned cell takes over the row's left gutter so it stays\n // flush with the scroll container edge — without this the row\n // padding scrolls away and leaves a transparent strip.\n ...(didFloat && { paddingLeft: 0 }),\n ...style,\n }}\n >\n {renderedChildren}\n </Box>\n {!hideDivider && <Divider color={theme.colors.border.secondary} />}\n </RowRevealContext.Provider>\n );\n }\n);\n\nTableRow.displayName = \"Table.Row\";\n\nconst positionToFlex = (position: TableCellProps[\"position\"]) => {\n switch (position) {\n case \"left\":\n return { flexShrink: 0 };\n case \"right\":\n return { flexShrink: 0, marginLeft: \"auto\" };\n default:\n return {};\n }\n};\n\nconst alignToJustify = (align: TableCellProps[\"align\"]) => {\n switch (align) {\n case \"right\":\n return \"flex-end\" as const;\n case \"center\":\n return \"center\" as const;\n default:\n return \"flex-start\" as const;\n }\n};\n\nconst TableCell = forwardRef<any, TableCellProps>(\n (\n {\n children,\n align = \"left\",\n position = \"default\",\n width,\n grow,\n revealOnHover,\n __floating,\n testID,\n themeMode,\n themeProductContext,\n style,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n const { revealed } = useContext(RowRevealContext);\n\n const positionStyle = useMemo(() => positionToFlex(position), [position]);\n\n // Per Figma spec: hide via opacity + pointer-events (NOT visibility) so\n // keyboard Tab still focuses the descendants. Focusing a descendant flips\n // `revealed` to true via RowRevealContext, restoring pointer-events.\n const revealStyle: React.CSSProperties =\n revealOnHover && !revealed\n ? { opacity: 0, pointerEvents: \"none\" }\n : revealOnHover\n ? { opacity: 1, transition: \"opacity 0.15s ease\" }\n : {};\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={alignToJustify(align)}\n gap={8}\n height=\"100%\"\n width={width}\n role=\"cell\"\n {...props}\n style={{\n flex: width != null ? \"0 0 auto\" : (grow ?? 1),\n minWidth: 0,\n ...positionStyle,\n ...revealStyle,\n ...(__floating && floatingCellStyle(__floating)),\n ...style,\n }}\n >\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Text\n fontSize={sizing.cellFontSize}\n lineHeight={sizing.cellLineHeight}\n color={theme.colors.content.primary}\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n maxWidth: \"100%\",\n }}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </Box>\n );\n }\n);\n\nTableCell.displayName = \"Table.Cell\";\n\n/**\n * Sort indicator. Uses the `Sort` line icon from `@xsolla/xui-icons-base`\n * (matches the Figma spec — a stacked up/down chevron). The icon is the\n * same in all three states; opacity differentiates \"sortable but not\n * active\" (`none`, 40%) from \"active sort\" (`ascending` / `descending`,\n * 100%). Direction is communicated to assistive tech via `aria-sort` on\n * the parent <Table.Head>.\n */\nconst SortIcon: React.FC<{\n direction: \"ascending\" | \"descending\" | \"none\";\n color: string;\n size: number;\n}> = ({ direction, color, size }) => (\n <Box\n style={{\n flexShrink: 0,\n opacity: direction === \"none\" ? 0.4 : 1,\n transition: \"opacity 0.15s ease\",\n }}\n >\n <Sort variant=\"line\" size={size} color={color} aria-hidden />\n </Box>\n);\n\nconst TableHead = forwardRef<any, TableHeadProps>(\n (\n {\n children,\n align = \"left\",\n position = \"default\",\n width,\n grow,\n sort,\n onSortToggle,\n __floating,\n testID,\n themeMode,\n themeProductContext,\n style,\n ...props\n },\n ref\n ) => {\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n const sizing = theme.sizing.table;\n\n const positionStyle = useMemo(() => positionToFlex(position), [position]);\n const sortable = sort != null;\n\n const ariaSort: \"ascending\" | \"descending\" | \"none\" | undefined = sortable\n ? sort\n : undefined;\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent={alignToJustify(align)}\n gap={sizing.headerCellGap}\n height=\"100%\"\n width={width}\n role=\"columnheader\"\n aria-sort={ariaSort}\n cursor={sortable ? \"pointer\" : undefined}\n onPress={sortable ? onSortToggle : undefined}\n {...props}\n style={{\n flex: width != null ? \"0 0 auto\" : (grow ?? 1),\n minWidth: 0,\n ...positionStyle,\n ...(__floating && floatingCellStyle(__floating)),\n ...style,\n }}\n >\n {sortable && (\n <SortIcon\n direction={sort}\n color={theme.colors.content.secondary}\n size={sizing.headerCellFontSize + 2}\n />\n )}\n {typeof children === \"string\" || typeof children === \"number\" ? (\n <Text\n fontSize={sizing.headerCellFontSize}\n lineHeight={sizing.headerCellLineHeight}\n color={theme.colors.content.secondary}\n fontWeight=\"500\"\n style={{\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {children}\n </Text>\n ) : (\n children\n )}\n </Box>\n );\n }\n);\n\nTableHead.displayName = \"Table.Head\";\n\nconst TableFooter = forwardRef<any, TableFooterProps>(\n ({ children, style, ...props }, ref) => {\n const { theme } = useResolvedTheme();\n const sizing = theme.sizing.table;\n\n return (\n <Box\n ref={ref}\n flexDirection=\"row\"\n alignItems=\"center\"\n justifyContent=\"center\"\n gap={sizing.paginationGap}\n paddingHorizontal={sizing.paginationPaddingHorizontal}\n width=\"100%\"\n {...props}\n style={style}\n >\n {children}\n </Box>\n );\n }\n);\n\nTableFooter.displayName = \"Table.Footer\";\n\n/**\n * Wraps each contiguous run of <Table.Header> / <Table.Body> children in a\n * horizontal scroll viewport, so the header row and the body scroll in\n * lockstep and column labels stay aligned with their values.\n *\n * Everything else — <Table.Caption>, <Table.Footer>, and any\n * consumer-composed filter panel or item counter dropped in as a direct\n * child — is left outside the viewport and stays fixed to the container\n * width, per the Figma spec.\n *\n * Declared as a hoisted `function` so <Table> (defined above) can call it\n * while still referencing TableHeader / TableBody, which are declared later\n * in the module.\n */\nfunction wrapRowGroupsInScrollViewport(\n children: ReactNode,\n scrollBar: boolean\n): ReactNode {\n const viewportStyle: React.CSSProperties = {\n overflowX: \"auto\",\n WebkitOverflowScrolling: \"touch\",\n // `false` hides the scrollbar without disabling the scrolling itself.\n ...(scrollBar\n ? { scrollbarWidth: \"thin\" as const }\n : { scrollbarWidth: \"none\" as const, msOverflowStyle: \"none\" as const }),\n };\n\n const out: ReactNode[] = [];\n let run: ReactNode[] = [];\n\n const flush = () => {\n if (run.length === 0) return;\n const group = run;\n run = [];\n out.push(\n <Box\n key={`__table-scroll-${out.length}`}\n width=\"100%\"\n style={viewportStyle}\n >\n {/* `max-content` lets the browser compute the natural row width, so\n the card background and the cells stay the same width when\n scrolled. Never hard-code a pixel min-width here. */}\n <Box\n flexDirection=\"column\"\n alignItems=\"stretch\"\n style={{ minWidth: \"max-content\" }}\n >\n {group}\n </Box>\n </Box>\n );\n };\n\n React.Children.toArray(children).forEach((child) => {\n const isRowGroup =\n React.isValidElement(child) &&\n (child.type === TableHeader || child.type === TableBody);\n if (isRowGroup) {\n run.push(child);\n return;\n }\n flush();\n out.push(child);\n });\n flush();\n\n return out;\n}\n\nexport const Table = Object.assign(TableRoot, {\n Caption: TableCaption,\n Header: TableHeader,\n Body: TableBody,\n Footer: TableFooter,\n Row: TableRow,\n Head: TableHead,\n Cell: TableCell,\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\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 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 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;AAAA;AAAA;AAAA;AAAA;;;ACAA,mBASO;;;ACRP,0BASO;AAwMD;AArMN,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;AAEO,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,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;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;;;AC3QA,IAAAA,uBAKO;AAqEH,IAAAC,sBAAA;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,gCAAW,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;AAAA,IAAC,qBAAAC;AAAA,IAAA;AAAA,MACC,OAAO;AAAA,MACP;AAAA,MACA,QAAQ,cAAc,UAAU;AAAA,MAChC;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;;;AFxEA,sBAA2C;AAC3C,4BAAqB;AAwEnB,IAAAC,sBAAA;AApDF,IAAM,2BAAuB,4BAAwB,MAAM;AAY3D,IAAM,yBAAqB,4BAA2B;AAAA,EACpD,QAAQ;AAAA,EACR,kBAAkB;AACpB,CAAC;AAQD,IAAM,uBAAmB,4BAAqC;AAAA,EAC5D,UAAU;AACZ,CAAC;AAYD,IAAM,kBAAkB,MAAe;AACrC,QAAM,CAAC,cAAc,eAAe,QAAI,uBAAS,IAAI;AACrD,8BAAU,MAAM;AACd,QAAI,yBAAU;AACd,QAAI,OAAO,WAAW,eAAe,CAAC,OAAO,WAAY;AACzD,UAAM,KAAK,OAAO,WAAW,gBAAgB;AAC7C,oBAAgB,GAAG,OAAO;AAC1B,UAAM,WAAW,CAAC,MAA2B,gBAAgB,EAAE,OAAO;AACtE,OAAG,mBAAmB,UAAU,QAAQ;AACxC,WAAO,MAAM,GAAG,sBAAsB,UAAU,QAAQ;AAAA,EAC1D,GAAG,CAAC,CAAC;AACL,SAAO;AACT;AAEA,IAAM,UAAuC,CAAC,EAAE,MAAM,MACpD;AAAA,EAAC;AAAA;AAAA,IACC,OAAM;AAAA,IACN,QAAQ;AAAA,IACR,iBAAiB;AAAA,IACjB,OAAO,EAAE,YAAY,EAAE;AAAA;AACzB;AASF,IAAM,oBAAoB,CACxB,cACyB;AAAA,EACzB,UAAU;AAAA,EACV,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,iBAAiB,SAAS;AAAA,EAC1B,aAAa,SAAS;AAAA,EACtB,WAAW,SAAS;AACtB;AAEA,IAAM,gBAAY;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA,YAAY;AAAA,IACZ,mBAAmB;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACA,QACG;AACH,UAAM,EAAE,MAAM,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,UAAM,SAAS,MAAM,OAAO;AAK5B,UAAM,eAAe,oBAAoB,WAAW;AAIpD,UAAM,gBAAgB,WAAW,WAAW,YAAY;AAExD,UAAM,aAAS;AAAA,MACb,OAAO,EAAE,QAAQ,kBAAkB,aAAa;AAAA,MAChD,CAAC,QAAQ,YAAY;AAAA,IACvB;AAEA,UAAM,UAAU,gBACZ,8BAA8B,UAAU,SAAS,IACjD;AAEJ,WACE,6CAAC,mBAAmB,UAAnB,EAA4B,OAAO,QAClC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,KAAK,OAAO;AAAA,QACZ,iBAAiB,OAAO;AAAA,QACxB,iBAAiB,MAAM,OAAO,WAAW;AAAA,QACzC,cAAc,OAAO;AAAA,QACrB,OAAM;AAAA,QACN,MAAK;AAAA,QACL,OAAO;AAAA,UACL,OAAO,MAAM,OAAO,QAAQ;AAAA,UAC5B,UAAU;AAAA,QACZ;AAAA,QAEC;AAAA;AAAA,IACH,GACF;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAExB,IAAM,mBAAe;AAAA,EACnB,CAAC,EAAE,UAAU,WAAW,qBAAqB,OAAO,GAAG,MAAM,GAAG,QAAQ;AACtE,UAAM,EAAE,MAAM,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,UAAM,SAAS,MAAM,OAAO;AAE5B,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,mBAAmB,OAAO;AAAA,QAC1B,OAAM;AAAA,QAGL,GAAG;AAAA,QACJ;AAAA,QAEC,iBAAO,aAAa,YAAY,OAAO,aAAa,WACnD;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,OAAO;AAAA,YACjB,YAAY,OAAO;AAAA,YACnB,OAAO,MAAM,OAAO,QAAQ;AAAA,YAE3B;AAAA;AAAA,QACH,IAEA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,aAAa,cAAc;AAE3B,IAAM,kBAAc;AAAA,EAClB,CAAC,EAAE,UAAU,WAAW,qBAAqB,OAAO,GAAG,MAAM,GAAG,QAAQ;AACtE,UAAM,EAAE,MAAM,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AAErE,WACE,6CAAC,qBAAqB,UAArB,EAA8B,OAAM,UACnC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,OAAM;AAAA,QACN,MAAK;AAAA,QACJ,GAAG;AAAA,QACJ,OAAO;AAAA,UACL,UAAU;AAAA,UACV,KAAK;AAAA,UACL,QAAQ;AAAA,UACR,iBAAiB,MAAM,OAAO,WAAW;AAAA,UACzC,GAAG;AAAA,QACL;AAAA,QAEC;AAAA;AAAA,UACD,6CAAC,WAAQ,OAAO,MAAM,OAAO,OAAO,WAAW;AAAA;AAAA;AAAA,IACjD,GACF;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;AAE1B,IAAM,gBAAY;AAAA,EAChB,CACE,EAAE,UAAU,OAAO,SAAS,WAAW,qBAAqB,GAAG,MAAM,GACrE,QACG;AACH,UAAM,EAAE,MAAM,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,UAAM,SAAS,MAAM,OAAO;AAM5B,UAAM,iBAAiB;AACvB,UAAM,oBAAoB,UACtB,UAAU,OAAO,aAAa,UAAU,KAAK,iBAC7C;AAMJ,QAAI,mBAA8B;AAClC,QAAI,SAAS;AACX,YAAM,aAAa,aAAAC,QAAM,SAAS,QAAQ,QAAQ;AAClD,YAAM,qBACJ,WAAW,SAAS,KACpB,WAAW,MAAM,CAAC,MAAM,aAAAA,QAAM,eAAe,CAAC,KAAK,EAAE,SAAS,QAAQ;AACxE,YAAM,eAAe,qBAAqB,WAAW,SAAS;AAC9D,YAAM,mBAAmB,qBACrB,KAAK,IAAI,GAAG,UAAU,YAAY,IAClC;AAEJ,UAAI,mBAAmB,GAAG;AAIxB,cAAM,cAAc,WAAW,IAAI,CAAC,OAAO,MAAM;AAC/C,cAAI,CAAC,aAAAA,QAAM,eAAe,KAAK,EAAG,QAAO;AACzC,gBAAM,gBAAgB,MAAM,eAAe;AAC3C,iBAAO,aAAAA,QAAM,aAAa,OAAO;AAAA,YAC/B,aAAa,gBACT,QACC,MAAM,MAAc;AAAA,UAC3B,CAAQ;AAAA,QACV,CAAC;AAED,cAAM,eAAe,MAAM,KAAK,EAAE,QAAQ,iBAAiB,CAAC,EAAE;AAAA,UAC5D,CAAC,GAAG,MAAM;AACR,kBAAM,SAAS,MAAM,mBAAmB;AACxC,mBACE;AAAA,cAAC;AAAA;AAAA,gBAEC,eAAW;AAAA,gBACX,OAAO;AAAA,kBACL,QAAQ,SACJ,OAAO,YACP,OAAO,YAAY;AAAA,kBACvB,YAAY;AAAA,gBACd;AAAA;AAAA,cAPK,4BAA4B,CAAC;AAAA,YAQpC;AAAA,UAEJ;AAAA,QACF;AAEA,2BACE,8EACG;AAAA;AAAA,UACA;AAAA,WACH;AAAA,MAEJ;AAAA,IACF;AAEA,WACE,6CAAC,qBAAqB,UAArB,EAA8B,OAAM,QACnC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,OAAM;AAAA,QACN,MAAK;AAAA,QACJ,GAAG;AAAA,QACJ,OAAO;AAAA,UACL,GAAI,sBAAsB,UAAa;AAAA,YACrC,WAAW;AAAA,UACb;AAAA,UACA,GAAG;AAAA,QACL;AAAA,QAEC;AAAA;AAAA,IACH,GACF;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAExB,IAAM,eAAW;AAAA,EACf,CACE;AAAA,IACE;AAAA,IACA,WAAW;AAAA,IACX;AAAA,IACA,aAAa;AAAA,IACb;AAAA,IACA;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,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,UAAM,SAAS,MAAM,OAAO;AAC5B,UAAM,eAAW,yBAAW,oBAAoB;AAChD,UAAM,EAAE,QAAQ,iBAAiB,QAAI,yBAAW,kBAAkB;AAClE,UAAM,eAAe,gBAAgB;AAErC,UAAM,cAAc,aAAa;AAIjC,UAAM,YAAY,iBAAiB,CAAC;AACpC,UAAM,cAAc,mBAAmB;AAKvC,UAAM,CAAC,SAAS,UAAU,QAAI,uBAAS,KAAK;AAC5C,UAAM,CAAC,eAAe,gBAAgB,QAAI,uBAAS,KAAK;AAKxD,UAAM,WACJ,WAAW,YAAY,CAAC,eAAe,OAAO,WAAW;AAE3D,UAAM,uBAAmB;AAAA,MACvB,CAAC,MAAqC;AACpC,mBAAW,IAAI;AACf,uBAAe,CAAC;AAAA,MAClB;AAAA,MACA,CAAC,YAAY;AAAA,IACf;AACA,UAAM,uBAAmB;AAAA,MACvB,CAAC,MAAqC;AACpC,mBAAW,KAAK;AAChB,uBAAe,CAAC;AAAA,MAClB;AAAA,MACA,CAAC,YAAY;AAAA,IACf;AACA,UAAM,kBAAc;AAAA,MAClB,CAAC,MAAqC;AACpC,yBAAiB,IAAI;AACrB,kBAAU,CAAC;AAAA,MACb;AAAA,MACA,CAAC,OAAO;AAAA,IACV;AACA,UAAM,iBAAa;AAAA,MACjB,CAAC,MAAqC;AAGpC,YACE,EAAE,yBAAyB,QAC3B,EAAE,cAAc,SAAS,EAAE,aAAa,GACxC;AACA,mBAAS,CAAC;AACV;AAAA,QACF;AACA,yBAAiB,KAAK;AACtB,iBAAS,CAAC;AAAA,MACZ;AAAA,MACA,CAAC,MAAM;AAAA,IACT;AAKA,UAAM,oBAAgB;AAAA,MACpB,CAAC,MAAoC;AACnC,oBAAY,CAAC;AACb,YAAI,CAAC,WAAW,EAAE,iBAAkB;AACpC,YAAI,EAAE,QAAQ,WAAW,EAAE,QAAQ,KAAK;AACtC,YAAE,eAAe;AACjB,kBAAQ;AAAA,QACV;AAAA,MACF;AAAA,MACA,CAAC,WAAW,OAAO;AAAA,IACrB;AAEA,UAAM,SAAS,WACX,MAAM,OAAO,WAAW,YACxB,MAAM,OAAO,WAAW;AAE5B,UAAM,YAAY,cAAc,OAAO,kBAAkB,OAAO;AAChE,UAAM,uBAAuB,cACzB,OAAO,6BACP,OAAO;AAEX,UAAM,eAAW,sBAAQ,OAAO,EAAE,SAAS,IAAI,CAAC,QAAQ,CAAC;AAKzD,UAAM,aACJ,aAAa,UAAU,MAAM,OAAO,WAAW,YAAY;AAK7D,QAAI,mBAA8B;AAClC,QAAI,WAAW;AACf,QAAI,kBAAkB;AACpB,YAAM,aAAa,aAAAA,QAAM,SAAS,QAAQ,QAAQ;AAClD,YAAM,iBAAiB,WAAW;AAAA,QAChC,CAAC,MACC,aAAAA,QAAM,eAAe,CAAC,MACrB,EAAE,SAAS,aAAa,EAAE,SAAS;AAAA,MACxC;AAEA,UAAI,mBAAmB,IAAI;AACzB,mBAAW;AACX,cAAM,WAAoC;AAAA,UACxC,YAAY;AAAA,UACZ,aAAa;AAAA,UACb,QAAQ,MAAM,OAAO;AAAA,QACvB;AACA,2BAAmB,WAAW;AAAA,UAAI,CAAC,OAAO,MACxC,MAAM,kBAAkB,aAAAA,QAAM,eAAe,KAAK,IAC9C,aAAAA,QAAM,aAAa,OAAO,EAAE,YAAY,SAAS,CAAQ,IACzD;AAAA,QACN;AAAA,MACF;AAAA,IACF;AAEA,WACE,8CAAC,iBAAiB,UAAjB,EAA0B,OAAO,UAChC;AAAA;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,eAAc;AAAA,UACd,YAAW;AAAA,UACX,QAAQ;AAAA,UACR,mBAAmB;AAAA,UACnB,OAAM;AAAA,UACN,KAAK,OAAO;AAAA,UACZ,iBAAiB;AAAA,UACjB,QAAQ,UAAU,YAAY;AAAA,UAC9B,YACE,YACI,EAAE,iBAAiB,MAAM,OAAO,WAAW,UAAU,IACrD;AAAA,UAEN;AAAA,UACA,MAAK;AAAA,UACL,UAAU,UAAU,IAAI;AAAA,UACxB,iBAAe,YAAY;AAAA,UAC3B,cAAc;AAAA,UACd,cAAc;AAAA,UACd,SAAS;AAAA,UACT,QAAQ;AAAA,UACP,GAAG;AAAA,UACJ,WAAW;AAAA,UACX,OAAO;AAAA;AAAA;AAAA;AAAA,YAIL,GAAI,YAAY,EAAE,aAAa,EAAE;AAAA,YACjC,GAAG;AAAA,UACL;AAAA,UAEC;AAAA;AAAA,MACH;AAAA,MACC,CAAC,eAAe,6CAAC,WAAQ,OAAO,MAAM,OAAO,OAAO,WAAW;AAAA,OAClE;AAAA,EAEJ;AACF;AAEA,SAAS,cAAc;AAEvB,IAAM,iBAAiB,CAAC,aAAyC;AAC/D,UAAQ,UAAU;AAAA,IAChB,KAAK;AACH,aAAO,EAAE,YAAY,EAAE;AAAA,IACzB,KAAK;AACH,aAAO,EAAE,YAAY,GAAG,YAAY,OAAO;AAAA,IAC7C;AACE,aAAO,CAAC;AAAA,EACZ;AACF;AAEA,IAAM,iBAAiB,CAAC,UAAmC;AACzD,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEA,IAAM,gBAAY;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,IACR,WAAW;AAAA,IACX;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,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,UAAM,SAAS,MAAM,OAAO;AAC5B,UAAM,EAAE,SAAS,QAAI,yBAAW,gBAAgB;AAEhD,UAAM,oBAAgB,sBAAQ,MAAM,eAAe,QAAQ,GAAG,CAAC,QAAQ,CAAC;AAKxE,UAAM,cACJ,iBAAiB,CAAC,WACd,EAAE,SAAS,GAAG,eAAe,OAAO,IACpC,gBACE,EAAE,SAAS,GAAG,YAAY,qBAAqB,IAC/C,CAAC;AAET,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,gBAAgB,eAAe,KAAK;AAAA,QACpC,KAAK;AAAA,QACL,QAAO;AAAA,QACP;AAAA,QACA,MAAK;AAAA,QACJ,GAAG;AAAA,QACJ,OAAO;AAAA,UACL,MAAM,SAAS,OAAO,aAAc,QAAQ;AAAA,UAC5C,UAAU;AAAA,UACV,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAI,cAAc,kBAAkB,UAAU;AAAA,UAC9C,GAAG;AAAA,QACL;AAAA,QAEC,iBAAO,aAAa,YAAY,OAAO,aAAa,WACnD;AAAA,UAAC;AAAA;AAAA,YACC,UAAU,OAAO;AAAA,YACjB,YAAY,OAAO;AAAA,YACnB,OAAO,MAAM,OAAO,QAAQ;AAAA,YAC5B,OAAO;AAAA,cACL,UAAU;AAAA,cACV,cAAc;AAAA,cACd,YAAY;AAAA,cACZ,UAAU;AAAA,YACZ;AAAA,YAEC;AAAA;AAAA,QACH,IAEA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAUxB,IAAM,WAID,CAAC,EAAE,WAAW,OAAO,KAAK,MAC7B;AAAA,EAAC;AAAA;AAAA,IACC,OAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS,cAAc,SAAS,MAAM;AAAA,MACtC,YAAY;AAAA,IACd;AAAA,IAEA,uDAAC,8BAAK,SAAQ,QAAO,MAAY,OAAc,eAAW,MAAC;AAAA;AAC7D;AAGF,IAAM,gBAAY;AAAA,EAChB,CACE;AAAA,IACE;AAAA,IACA,QAAQ;AAAA,IACR,WAAW;AAAA,IACX;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,QAAI,kCAAiB,EAAE,WAAW,oBAAoB,CAAC;AACrE,UAAM,SAAS,MAAM,OAAO;AAE5B,UAAM,oBAAgB,sBAAQ,MAAM,eAAe,QAAQ,GAAG,CAAC,QAAQ,CAAC;AACxE,UAAM,WAAW,QAAQ;AAEzB,UAAM,WAA4D,WAC9D,OACA;AAEJ,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,gBAAgB,eAAe,KAAK;AAAA,QACpC,KAAK,OAAO;AAAA,QACZ,QAAO;AAAA,QACP;AAAA,QACA,MAAK;AAAA,QACL,aAAW;AAAA,QACX,QAAQ,WAAW,YAAY;AAAA,QAC/B,SAAS,WAAW,eAAe;AAAA,QAClC,GAAG;AAAA,QACJ,OAAO;AAAA,UACL,MAAM,SAAS,OAAO,aAAc,QAAQ;AAAA,UAC5C,UAAU;AAAA,UACV,GAAG;AAAA,UACH,GAAI,cAAc,kBAAkB,UAAU;AAAA,UAC9C,GAAG;AAAA,QACL;AAAA,QAEC;AAAA,sBACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAW;AAAA,cACX,OAAO,MAAM,OAAO,QAAQ;AAAA,cAC5B,MAAM,OAAO,qBAAqB;AAAA;AAAA,UACpC;AAAA,UAED,OAAO,aAAa,YAAY,OAAO,aAAa,WACnD;AAAA,YAAC;AAAA;AAAA,cACC,UAAU,OAAO;AAAA,cACjB,YAAY,OAAO;AAAA,cACnB,OAAO,MAAM,OAAO,QAAQ;AAAA,cAC5B,YAAW;AAAA,cACX,OAAO;AAAA,gBACL,UAAU;AAAA,gBACV,cAAc;AAAA,gBACd,YAAY;AAAA,cACd;AAAA,cAEC;AAAA;AAAA,UACH,IAEA;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,UAAU,cAAc;AAExB,IAAM,kBAAc;AAAA,EAClB,CAAC,EAAE,UAAU,OAAO,GAAG,MAAM,GAAG,QAAQ;AACtC,UAAM,EAAE,MAAM,QAAI,kCAAiB;AACnC,UAAM,SAAS,MAAM,OAAO;AAE5B,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,eAAc;AAAA,QACd,YAAW;AAAA,QACX,gBAAe;AAAA,QACf,KAAK,OAAO;AAAA,QACZ,mBAAmB,OAAO;AAAA,QAC1B,OAAM;AAAA,QACL,GAAG;AAAA,QACJ;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,EAEJ;AACF;AAEA,YAAY,cAAc;AAgB1B,SAAS,8BACP,UACA,WACW;AACX,QAAM,gBAAqC;AAAA,IACzC,WAAW;AAAA,IACX,yBAAyB;AAAA;AAAA,IAEzB,GAAI,YACA,EAAE,gBAAgB,OAAgB,IAClC,EAAE,gBAAgB,QAAiB,iBAAiB,OAAgB;AAAA,EAC1E;AAEA,QAAM,MAAmB,CAAC;AAC1B,MAAI,MAAmB,CAAC;AAExB,QAAM,QAAQ,MAAM;AAClB,QAAI,IAAI,WAAW,EAAG;AACtB,UAAM,QAAQ;AACd,UAAM,CAAC;AACP,QAAI;AAAA,MACF;AAAA,QAAC;AAAA;AAAA,UAEC,OAAM;AAAA,UACN,OAAO;AAAA,UAKP;AAAA,YAAC;AAAA;AAAA,cACC,eAAc;AAAA,cACd,YAAW;AAAA,cACX,OAAO,EAAE,UAAU,cAAc;AAAA,cAEhC;AAAA;AAAA,UACH;AAAA;AAAA,QAbK,kBAAkB,IAAI,MAAM;AAAA,MAcnC;AAAA,IACF;AAAA,EACF;AAEA,eAAAA,QAAM,SAAS,QAAQ,QAAQ,EAAE,QAAQ,CAAC,UAAU;AAClD,UAAM,aACJ,aAAAA,QAAM,eAAe,KAAK,MACzB,MAAM,SAAS,eAAe,MAAM,SAAS;AAChD,QAAI,YAAY;AACd,UAAI,KAAK,KAAK;AACd;AAAA,IACF;AACA,UAAM;AACN,QAAI,KAAK,KAAK;AAAA,EAChB,CAAC;AACD,QAAM;AAEN,SAAO;AACT;AAEO,IAAM,QAAQ,OAAO,OAAO,WAAW;AAAA,EAC5C,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,MAAM;AACR,CAAC;","names":["import_react_native","import_jsx_runtime","RNText","import_jsx_runtime","React"]}
|
package/native/index.mjs
CHANGED
|
@@ -323,6 +323,10 @@ import { useResolvedTheme, isNative } from "@xsolla/xui-core";
|
|
|
323
323
|
import { Sort } from "@xsolla/xui-icons-base";
|
|
324
324
|
import { Fragment, jsx as jsx3, jsxs } from "react/jsx-runtime";
|
|
325
325
|
var TableRowGroupContext = createContext("body");
|
|
326
|
+
var TableConfigContext = createContext({
|
|
327
|
+
device: "desktop",
|
|
328
|
+
floatFirstColumn: false
|
|
329
|
+
});
|
|
326
330
|
var RowRevealContext = createContext({
|
|
327
331
|
revealed: true
|
|
328
332
|
});
|
|
@@ -348,11 +352,35 @@ var Divider = ({ color }) => /* @__PURE__ */ jsx3(
|
|
|
348
352
|
style: { flexShrink: 0 }
|
|
349
353
|
}
|
|
350
354
|
);
|
|
355
|
+
var floatingCellStyle = (floating) => ({
|
|
356
|
+
position: "sticky",
|
|
357
|
+
left: 0,
|
|
358
|
+
zIndex: 2,
|
|
359
|
+
backgroundColor: floating.background,
|
|
360
|
+
paddingLeft: floating.paddingLeft,
|
|
361
|
+
boxShadow: floating.shadow
|
|
362
|
+
});
|
|
351
363
|
var TableRoot = forwardRef(
|
|
352
|
-
({
|
|
364
|
+
({
|
|
365
|
+
children,
|
|
366
|
+
device = "desktop",
|
|
367
|
+
scroll,
|
|
368
|
+
scrollBar = false,
|
|
369
|
+
floatFirstColumn = false,
|
|
370
|
+
testID,
|
|
371
|
+
themeMode,
|
|
372
|
+
themeProductContext
|
|
373
|
+
}, ref) => {
|
|
353
374
|
const { theme } = useResolvedTheme({ themeMode, themeProductContext });
|
|
354
375
|
const sizing = theme.sizing.table;
|
|
355
|
-
|
|
376
|
+
const floatEnabled = floatFirstColumn && device !== "mobile";
|
|
377
|
+
const scrollEnabled = scroll ?? (device === "mobile" || floatEnabled);
|
|
378
|
+
const config = useMemo(
|
|
379
|
+
() => ({ device, floatFirstColumn: floatEnabled }),
|
|
380
|
+
[device, floatEnabled]
|
|
381
|
+
);
|
|
382
|
+
const content = scrollEnabled ? wrapRowGroupsInScrollViewport(children, scrollBar) : children;
|
|
383
|
+
return /* @__PURE__ */ jsx3(TableConfigContext.Provider, { value: config, children: /* @__PURE__ */ jsx3(
|
|
356
384
|
Box,
|
|
357
385
|
{
|
|
358
386
|
ref,
|
|
@@ -369,9 +397,9 @@ var TableRoot = forwardRef(
|
|
|
369
397
|
color: theme.colors.content.primary,
|
|
370
398
|
overflow: "clip"
|
|
371
399
|
},
|
|
372
|
-
children
|
|
400
|
+
children: content
|
|
373
401
|
}
|
|
374
|
-
);
|
|
402
|
+
) });
|
|
375
403
|
}
|
|
376
404
|
);
|
|
377
405
|
TableRoot.displayName = "Table";
|
|
@@ -515,13 +543,14 @@ var TableRow = forwardRef(
|
|
|
515
543
|
const { theme } = useResolvedTheme({ themeMode, themeProductContext });
|
|
516
544
|
const sizing = theme.sizing.table;
|
|
517
545
|
const rowGroup = useContext(TableRowGroupContext);
|
|
546
|
+
const { device, floatFirstColumn } = useContext(TableConfigContext);
|
|
518
547
|
const hoverCapable = useHoverCapable();
|
|
519
548
|
const isHeaderRow = rowGroup === "header";
|
|
520
549
|
const hoverable = hoverableProp ?? !isHeaderRow;
|
|
521
550
|
const hideDivider = hideDividerProp ?? isHeaderRow;
|
|
522
551
|
const [hovered, setHovered] = useState(false);
|
|
523
552
|
const [focusedWithin, setFocusedWithin] = useState(false);
|
|
524
|
-
const revealed = hoverCapable ? hovered || focusedWithin
|
|
553
|
+
const revealed = device === "mobile" || !hoverCapable ? true : hovered || focusedWithin;
|
|
525
554
|
const handleMouseEnter = useCallback(
|
|
526
555
|
(e) => {
|
|
527
556
|
setHovered(true);
|
|
@@ -569,6 +598,26 @@ var TableRow = forwardRef(
|
|
|
569
598
|
const rowHeight = isHeaderRow ? sizing.headerRowHeight : sizing.rowHeight;
|
|
570
599
|
const rowPaddingHorizontal = isHeaderRow ? sizing.headerRowPaddingHorizontal : sizing.rowPaddingHorizontal;
|
|
571
600
|
const ctxValue = useMemo(() => ({ revealed }), [revealed]);
|
|
601
|
+
const resolvedBg = hoverable && hovered ? theme.colors.background.secondary : baseBg;
|
|
602
|
+
let renderedChildren = children;
|
|
603
|
+
let didFloat = false;
|
|
604
|
+
if (floatFirstColumn) {
|
|
605
|
+
const childArray = React.Children.toArray(children);
|
|
606
|
+
const firstCellIndex = childArray.findIndex(
|
|
607
|
+
(c) => React.isValidElement(c) && (c.type === TableCell || c.type === TableHead)
|
|
608
|
+
);
|
|
609
|
+
if (firstCellIndex !== -1) {
|
|
610
|
+
didFloat = true;
|
|
611
|
+
const floating = {
|
|
612
|
+
background: resolvedBg,
|
|
613
|
+
paddingLeft: rowPaddingHorizontal,
|
|
614
|
+
shadow: theme.shadow.surface
|
|
615
|
+
};
|
|
616
|
+
renderedChildren = childArray.map(
|
|
617
|
+
(child, i) => i === firstCellIndex && React.isValidElement(child) ? React.cloneElement(child, { __floating: floating }) : child
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
}
|
|
572
621
|
return /* @__PURE__ */ jsxs(RowRevealContext.Provider, { value: ctxValue, children: [
|
|
573
622
|
/* @__PURE__ */ jsx3(
|
|
574
623
|
Box,
|
|
@@ -593,8 +642,14 @@ var TableRow = forwardRef(
|
|
|
593
642
|
onBlur: handleBlur,
|
|
594
643
|
...props,
|
|
595
644
|
onKeyDown: handleKeyDown,
|
|
596
|
-
style
|
|
597
|
-
|
|
645
|
+
style: {
|
|
646
|
+
// The pinned cell takes over the row's left gutter so it stays
|
|
647
|
+
// flush with the scroll container edge — without this the row
|
|
648
|
+
// padding scrolls away and leaves a transparent strip.
|
|
649
|
+
...didFloat && { paddingLeft: 0 },
|
|
650
|
+
...style
|
|
651
|
+
},
|
|
652
|
+
children: renderedChildren
|
|
598
653
|
}
|
|
599
654
|
),
|
|
600
655
|
!hideDivider && /* @__PURE__ */ jsx3(Divider, { color: theme.colors.border.secondary })
|
|
@@ -630,6 +685,7 @@ var TableCell = forwardRef(
|
|
|
630
685
|
width,
|
|
631
686
|
grow,
|
|
632
687
|
revealOnHover,
|
|
688
|
+
__floating,
|
|
633
689
|
testID,
|
|
634
690
|
themeMode,
|
|
635
691
|
themeProductContext,
|
|
@@ -658,6 +714,7 @@ var TableCell = forwardRef(
|
|
|
658
714
|
minWidth: 0,
|
|
659
715
|
...positionStyle,
|
|
660
716
|
...revealStyle,
|
|
717
|
+
...__floating && floatingCellStyle(__floating),
|
|
661
718
|
...style
|
|
662
719
|
},
|
|
663
720
|
children: typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx3(
|
|
@@ -700,6 +757,7 @@ var TableHead = forwardRef(
|
|
|
700
757
|
grow,
|
|
701
758
|
sort,
|
|
702
759
|
onSortToggle,
|
|
760
|
+
__floating,
|
|
703
761
|
testID,
|
|
704
762
|
themeMode,
|
|
705
763
|
themeProductContext,
|
|
@@ -730,6 +788,7 @@ var TableHead = forwardRef(
|
|
|
730
788
|
flex: width != null ? "0 0 auto" : grow ?? 1,
|
|
731
789
|
minWidth: 0,
|
|
732
790
|
...positionStyle,
|
|
791
|
+
...__floating && floatingCellStyle(__floating),
|
|
733
792
|
...style
|
|
734
793
|
},
|
|
735
794
|
children: [
|
|
@@ -784,6 +843,51 @@ var TableFooter = forwardRef(
|
|
|
784
843
|
}
|
|
785
844
|
);
|
|
786
845
|
TableFooter.displayName = "Table.Footer";
|
|
846
|
+
function wrapRowGroupsInScrollViewport(children, scrollBar) {
|
|
847
|
+
const viewportStyle = {
|
|
848
|
+
overflowX: "auto",
|
|
849
|
+
WebkitOverflowScrolling: "touch",
|
|
850
|
+
// `false` hides the scrollbar without disabling the scrolling itself.
|
|
851
|
+
...scrollBar ? { scrollbarWidth: "thin" } : { scrollbarWidth: "none", msOverflowStyle: "none" }
|
|
852
|
+
};
|
|
853
|
+
const out = [];
|
|
854
|
+
let run = [];
|
|
855
|
+
const flush = () => {
|
|
856
|
+
if (run.length === 0) return;
|
|
857
|
+
const group = run;
|
|
858
|
+
run = [];
|
|
859
|
+
out.push(
|
|
860
|
+
/* @__PURE__ */ jsx3(
|
|
861
|
+
Box,
|
|
862
|
+
{
|
|
863
|
+
width: "100%",
|
|
864
|
+
style: viewportStyle,
|
|
865
|
+
children: /* @__PURE__ */ jsx3(
|
|
866
|
+
Box,
|
|
867
|
+
{
|
|
868
|
+
flexDirection: "column",
|
|
869
|
+
alignItems: "stretch",
|
|
870
|
+
style: { minWidth: "max-content" },
|
|
871
|
+
children: group
|
|
872
|
+
}
|
|
873
|
+
)
|
|
874
|
+
},
|
|
875
|
+
`__table-scroll-${out.length}`
|
|
876
|
+
)
|
|
877
|
+
);
|
|
878
|
+
};
|
|
879
|
+
React.Children.toArray(children).forEach((child) => {
|
|
880
|
+
const isRowGroup = React.isValidElement(child) && (child.type === TableHeader || child.type === TableBody);
|
|
881
|
+
if (isRowGroup) {
|
|
882
|
+
run.push(child);
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
885
|
+
flush();
|
|
886
|
+
out.push(child);
|
|
887
|
+
});
|
|
888
|
+
flush();
|
|
889
|
+
return out;
|
|
890
|
+
}
|
|
787
891
|
var Table = Object.assign(TableRoot, {
|
|
788
892
|
Caption: TableCaption,
|
|
789
893
|
Header: TableHeader,
|