@xsolla/xui-tooltip 0.218.1 → 0.220.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.js +3 -0
- package/native/index.js.map +1 -1
- package/native/index.mjs +3 -0
- package/native/index.mjs.map +1 -1
- package/package.json +4 -4
- package/web/index.js +6 -2
- package/web/index.js.map +1 -1
- package/web/index.mjs +6 -2
- package/web/index.mjs.map +1 -1
package/native/index.js
CHANGED
|
@@ -70,6 +70,7 @@ var toGapValue = (gap) => {
|
|
|
70
70
|
const asNumber = Number(gap);
|
|
71
71
|
return Number.isFinite(asNumber) ? asNumber : void 0;
|
|
72
72
|
};
|
|
73
|
+
var toNativeDisplay = (display) => display === "none" ? "none" : void 0;
|
|
73
74
|
var Box = ({
|
|
74
75
|
children,
|
|
75
76
|
onPress,
|
|
@@ -101,6 +102,7 @@ var Box = ({
|
|
|
101
102
|
marginBottom,
|
|
102
103
|
marginLeft,
|
|
103
104
|
marginRight,
|
|
105
|
+
display,
|
|
104
106
|
flexDirection,
|
|
105
107
|
flexWrap,
|
|
106
108
|
alignItems,
|
|
@@ -164,6 +166,7 @@ var Box = ({
|
|
|
164
166
|
marginBottom,
|
|
165
167
|
marginLeft,
|
|
166
168
|
marginRight,
|
|
169
|
+
display: toNativeDisplay(display),
|
|
167
170
|
flexDirection,
|
|
168
171
|
flexWrap,
|
|
169
172
|
alignItems,
|
package/native/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/index.tsx","../../src/Tooltip.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/Portal.native.tsx","../../src/TooltipContentContext.tsx","../../src/contentTypography.ts","../../src/TooltipText.tsx","../../src/TooltipLink.tsx"],"sourcesContent":["export * from \"./Tooltip\";\nexport * from \"./TooltipText\";\nexport * from \"./TooltipLink\";\nexport * from \"./TooltipContentContext\";\nexport * from \"./contentTypography\";\nexport * from \"./types\";\n","import React, { forwardRef, useState, useMemo, useEffect, useRef } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n isNative,\n useModalId,\n useOverlayLayer,\n LAYER_OFFSET,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport type {\n TooltipContentStyles,\n TooltipPlacement,\n TooltipProps,\n TooltipSize,\n} from \"./types\";\nimport { Portal } from \"./Portal\";\nimport { TooltipContentContext } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipTypographyTokens,\n} from \"./contentTypography\";\n\nconst TOOLTIP_OPEN_EVENT = \"xui-tooltip-open\";\ntype TooltipTheme = {\n colors: {\n layer: {\n float: string;\n };\n content: {\n primary: string;\n brand: {\n primary: string;\n };\n };\n };\n shape: {\n tooltip: Record<TooltipSize, { borderRadius: number | string }>;\n };\n typographyTokens?: TooltipTypographyTokens;\n};\n\nconst ARROW_SIZE = 10;\nconst ARROW_HALF = ARROW_SIZE / 2;\n// Keeps the arrow clear of the panel's corner radius (8px for `md`).\nconst ARROW_EDGE_OFFSET = 12;\nconst ARROW_CENTER_INSET = ARROW_EDGE_OFFSET + ARROW_HALF;\n\n// Re-centres the arrow on triggers too narrow for the flush inset (FEP-889).\nconst getArrowAlignmentShift = (triggerWidth: number) =>\n Math.max(0, ARROW_CENTER_INSET - triggerWidth / 2);\n\nconst getPositionStyles = (\n triggerRect: DOMRect,\n placement: TooltipPlacement,\n offset: number,\n isVisible: boolean\n) => {\n const slideDistance = 8;\n const scale = isVisible ? \"scale(1)\" : \"scale(0.95)\";\n const slideOffset = isVisible ? 0 : -slideDistance;\n const arrowShift = getArrowAlignmentShift(triggerRect.width);\n\n switch (placement) {\n case \"top\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-left\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-right\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"bottom\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-left\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-right\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(${slideOffset}px) ${scale}`,\n };\n case \"left\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.left - offset,\n transform: `translateX(calc(-100% - ${slideOffset}px)) translateY(-50%) ${scale}`,\n };\n case \"right\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.right + offset,\n transform: `translateX(${slideOffset}px) translateY(-50%) ${scale}`,\n };\n default:\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n }\n};\n\nconst getArrowStyles = (placement: TooltipPlacement) => {\n const base: React.CSSProperties = {\n width: ARROW_SIZE,\n height: ARROW_SIZE,\n transform: \"rotate(45deg)\",\n borderRadius: 1,\n };\n\n const placementStyles: Record<TooltipPlacement, React.CSSProperties> = {\n top: { bottom: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"top-left\": { bottom: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"top-right\": { bottom: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n bottom: { top: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"bottom-left\": { top: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"bottom-right\": { top: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n left: { right: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n right: { left: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n };\n\n return { ...base, ...placementStyles[placement] };\n};\n\nexport const Tooltip = forwardRef<\n HTMLDivElement,\n TooltipProps & ThemeOverrideProps\n>(\n (\n {\n content,\n children,\n size = \"md\",\n delayEnter = 0,\n delayLeave = 100,\n offset = 12,\n placement = \"top\",\n maxWidth,\n controlledVisible,\n style,\n \"data-testid\": dataTestId,\n className,\n testID,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const [isHovered, setIsHovered] = useState(false);\n const [triggerRect, setTriggerRect] = useState<DOMRect | null>(null);\n const { theme: resolvedTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = resolvedTheme as TooltipTheme;\n const enterTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const leaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rafRef = useRef<number | null>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const tooltipId = useId();\n const modalId = useModalId();\n const overlayLayer = useOverlayLayer();\n\n const isVisible =\n controlledVisible !== undefined ? controlledVisible : isHovered;\n\n const clearPendingVisibilityUpdates = () => {\n if (enterTimeoutRef.current) {\n clearTimeout(enterTimeoutRef.current);\n enterTimeoutRef.current = null;\n }\n\n if (leaveTimeoutRef.current) {\n clearTimeout(leaveTimeoutRef.current);\n leaveTimeoutRef.current = null;\n }\n\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n const forceHideTooltip = () => {\n clearPendingVisibilityUpdates();\n setIsHovered(false);\n };\n\n const positionStyles = useMemo(\n () =>\n triggerRect\n ? getPositionStyles(triggerRect, placement, offset, isVisible)\n : { top: 0, left: 0 },\n [triggerRect, placement, offset, isVisible]\n );\n const typoStyles = useMemo(() => getTooltipTypoStyles(size), [size]);\n const borderRadius = (theme.shape.tooltip[size] ?? theme.shape.tooltip.md)\n .borderRadius;\n const arrowStyles = useMemo(() => getArrowStyles(placement), [placement]);\n\n // Published to arbitrary `content` so nested helpers (TooltipText,\n // TooltipLink) inherit this tooltip's size scale and colour tokens.\n const contentStyles = useMemo<TooltipContentStyles>(\n () => ({\n size,\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n color: theme.colors.content.primary,\n linkColor: theme.colors.content.brand.primary,\n }),\n [\n size,\n typoStyles,\n theme.colors.content.primary,\n theme.colors.content.brand.primary,\n ]\n );\n\n // Update trigger position when tooltip becomes visible and on scroll/resize\n useEffect(() => {\n if (!isVisible || isNative) return;\n\n const updatePosition = () => {\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n }\n };\n\n updatePosition();\n\n window.addEventListener(\"scroll\", updatePosition, true);\n window.addEventListener(\"resize\", updatePosition);\n\n return () => {\n window.removeEventListener(\"scroll\", updatePosition, true);\n window.removeEventListener(\"resize\", updatePosition);\n };\n }, [isVisible]);\n\n const showTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (!isNative && typeof document !== \"undefined\") {\n document.dispatchEvent(\n new CustomEvent(TOOLTIP_OPEN_EVENT, { detail: { tooltipId } })\n );\n }\n\n // Update position before showing to prevent pop-in\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n\n // Double RAF to ensure position is rendered before showing tooltip\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = requestAnimationFrame(() => {\n if (delayEnter > 0) {\n enterTimeoutRef.current = setTimeout(() => {\n setIsHovered(true);\n }, delayEnter);\n } else {\n setIsHovered(true);\n }\n });\n });\n }\n };\n\n const showTooltipOnFocus = (event: React.FocusEvent<HTMLElement>) => {\n // Only reveal the tooltip on intentional keyboard focus. Focus that the\n // browser restores to the trigger when the tab/window regains focus — as\n // well as focus from a mouse click — must not re-trigger the tooltip\n // (FEP-832). `:focus-visible` encodes exactly this heuristic: it matches\n // for keyboard navigation but not for pointer-driven or restored focus.\n const target = event.target as HTMLElement | null;\n\n if (target && typeof target.matches === \"function\") {\n let isFocusVisible: boolean;\n try {\n isFocusVisible = target.matches(\":focus-visible\");\n } catch {\n // Legacy browsers without :focus-visible support — preserve the\n // previous behaviour of showing on any focus.\n isFocusVisible = true;\n }\n\n if (!isFocusVisible) return;\n }\n\n showTooltip();\n };\n\n const hideTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (delayLeave > 0) {\n leaveTimeoutRef.current = setTimeout(() => {\n setIsHovered(false);\n }, delayLeave);\n } else {\n setIsHovered(false);\n }\n };\n\n useEffect(() => {\n if (isNative) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && isVisible) {\n forceHideTooltip();\n }\n };\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") {\n forceHideTooltip();\n }\n };\n\n const handleTooltipOpen = (event: Event) => {\n const { tooltipId: activeTooltipId } =\n (event as CustomEvent).detail ?? {};\n\n if (activeTooltipId !== tooltipId) {\n forceHideTooltip();\n }\n };\n\n document.addEventListener(\"keydown\", handleEscape);\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n document.addEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n\n return () => {\n document.removeEventListener(\"keydown\", handleEscape);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n document.removeEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n clearPendingVisibilityUpdates();\n };\n }, [isVisible, tooltipId]);\n\n return (\n <Box\n testID={testID}\n ref={triggerRef}\n position=\"relative\"\n display=\"inline-flex\"\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n onFocus={showTooltipOnFocus}\n onBlur={hideTooltip}\n className={className}\n style={{ height: \"fit-content\" }}\n aria-describedby={isVisible ? tooltipId : undefined}\n >\n {children}\n {!isNative && triggerRect && (\n <Portal>\n <Box\n ref={ref}\n data-testid={dataTestId}\n data-modal-id={modalId}\n position=\"fixed\"\n backgroundColor={theme.colors.layer.float}\n borderRadius={borderRadius}\n paddingVertical={8}\n paddingHorizontal={12}\n zIndex={overlayLayer + LAYER_OFFSET.tooltip}\n id={tooltipId}\n role=\"tooltip\"\n aria-hidden={!isVisible}\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n style={{\n ...positionStyles,\n // https://stackoverflow.com/questions/62844007/how-to-apply-tool-tip-arrow-triangle-shadow\n filter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n WebkitFilter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? \"visible\" : \"hidden\",\n transition:\n \"opacity 150ms cubic-bezier(.4,0,.2,1), transform 150ms cubic-bezier(.4,0,.2,1), visibility 150ms cubic-bezier(.4,0,.2,1)\",\n pointerEvents: isVisible ? \"auto\" : \"none\",\n whiteSpace: \"normal\",\n width: \"max-content\",\n maxWidth: maxWidth ?? \"none\",\n overflow: \"visible\",\n willChange: isVisible ? \"transform, opacity\" : \"auto\", // optimize rendering and ensure more stable positioning\n ...style,\n }}\n >\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.layer.float}\n style={{\n ...arrowStyles,\n backfaceVisibility: \"hidden\",\n WebkitBackfaceVisibility: \"hidden\",\n }}\n />\n <TooltipContentContext.Provider value={contentStyles}>\n <Box\n style={{\n wordWrap: \"break-word\",\n overflowWrap: \"break-word\",\n maxWidth: \"100%\",\n whiteSpace: \"normal\",\n // Custom `content` inherits the tooltip's own type scale,\n // so plain markup (`<strong>`, `<a>`, bare strings) reads\n // at the right size without re-deriving it per call site.\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n fontWeight: DEFAULT_BODY_FONT_WEIGHT,\n color: theme.colors.content.primary,\n }}\n >\n {typeof content === \"string\" || typeof content === \"number\" ? (\n <Text\n color={theme.colors.content.primary}\n fontSize={typoStyles.fontSize}\n fontWeight={String(DEFAULT_BODY_FONT_WEIGHT)}\n style={{\n lineHeight: typoStyles.lineHeight,\n whiteSpace: \"pre-line\",\n }}\n >\n {content}\n </Text>\n ) : (\n content\n )}\n </Box>\n </TooltipContentContext.Provider>\n </Box>\n </Portal>\n )}\n </Box>\n );\n }\n);\n\nTooltip.displayName = \"Tooltip\";\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","import { ReactNode } from \"react\";\n\ninterface PortalProps {\n children: ReactNode;\n}\n\n// Portal not supported on React Native - tooltip content renders inline\nexport const Portal = ({ children }: PortalProps) => {\n return <>{children}</>;\n};\n","import { createContext, useContext } from \"react\";\nimport type { TooltipContentStyles } from \"./types\";\n\n/**\n * Publishes the surrounding tooltip's resolved typography and colour tokens to\n * whatever is rendered inside its `content`, so `TooltipText` / `TooltipLink`\n * inherit the tooltip's size without the caller repeating it.\n *\n * `null` when the consumer is rendered outside a `Tooltip` — the helpers then\n * fall back to their own defaults.\n */\nexport const TooltipContentContext = createContext<TooltipContentStyles | null>(\n null\n);\n\nexport const useTooltipContentStyles = (): TooltipContentStyles | null =>\n useContext(TooltipContentContext);\n","import type { TooltipSize } from \"./types\";\n\n/**\n * Per-size font metrics for tooltip copy. Mirrors the tooltip size matrix in\n * the Figma UI kit (node 5680-32928).\n */\nexport const getTooltipTypoStyles = (size: TooltipSize) => {\n switch (size) {\n case \"sm\":\n return { fontSize: 14, lineHeight: \"16px\" };\n case \"md\":\n return { fontSize: 16, lineHeight: \"18px\" };\n case \"lg\":\n return { fontSize: 18, lineHeight: \"20px\" };\n case \"xl\":\n return { fontSize: 20, lineHeight: \"22px\" };\n default:\n return { fontSize: 16, lineHeight: \"18px\" };\n }\n};\n\n/**\n * Body typography token whose scale matches each tooltip size. Used to resolve\n * the *accent* (bold) font weight for emphasised copy inside a tooltip.\n *\n * `xl` has no body token of its own — the body scale tops out at 18px\n * (`body-lg`) — so it reuses `body-lg`'s accent weight rather than hardcoding\n * a weight the active product context may not use.\n */\nconst TOOLTIP_BODY_VARIANT: Record<TooltipSize, string> = {\n sm: \"body-sm\",\n md: \"body-md\",\n lg: \"body-lg\",\n xl: \"body-lg\",\n};\n\n/** Fallbacks for a resolved theme that predates `typographyTokens`. */\nexport const DEFAULT_BODY_FONT_WEIGHT = 400;\nexport const DEFAULT_ACCENT_FONT_WEIGHT = 500;\n\nexport interface TooltipTypographyTokens {\n basic?: Record<\n string,\n { fontWeight?: number; accent?: { fontWeight?: number } } | undefined\n >;\n}\n\n/** The slice of the resolved theme this module reads. */\nexport interface TooltipThemeTypography {\n typographyTokens?: TooltipTypographyTokens;\n}\n\n/**\n * Resolves the accent font weight for `size` from the theme's body typography\n * scale, so bold tooltip copy follows the active product context (b2b/b2c use\n * 500, corpsite uses 600) instead of a hardcoded weight.\n */\nexport const getTooltipAccentFontWeight = (\n typographyTokens: TooltipTypographyTokens | undefined,\n size: TooltipSize\n): number => {\n const variant = TOOLTIP_BODY_VARIANT[size] ?? TOOLTIP_BODY_VARIANT.md;\n\n return (\n typographyTokens?.basic?.[variant]?.accent?.fontWeight ??\n DEFAULT_ACCENT_FONT_WEIGHT\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipTextProps } from \"./types\";\n\n/**\n * Text inside a `Tooltip`'s `content`, styled with the tooltip's own size\n * scale and `content/primary` colour.\n *\n * Pass `accent` for bold copy — the weight is read from the body accent token\n * matching the tooltip's size, so it tracks the active product context instead\n * of a hardcoded `700`.\n */\nexport const TooltipText: React.FC<TooltipTextProps & ThemeOverrideProps> = ({\n children,\n accent = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.color ?? theme.colors.content.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n return (\n <Text\n testID={testID}\n data-testid={dataTestId}\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n style={{\n lineHeight: typo.lineHeight,\n whiteSpace: \"pre-line\",\n ...style,\n }}\n >\n {children}\n </Text>\n );\n};\n\nTooltipText.displayName = \"TooltipText\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipLinkProps } from \"./types\";\n\n/**\n * A link inside a `Tooltip`'s `content`. Uses the `content/brand-primary`\n * token and the tooltip's own size scale, so it sits inline with surrounding\n * `TooltipText` without the caller re-deriving typography.\n *\n * The tooltip surface is hoverable, so the link is reachable with a pointer.\n * It is **not** reachable by keyboard — tabbing away from the trigger blurs it\n * and dismisses the tooltip. When a link must be keyboard-operable, use\n * [Toggletip](../../toggletip) instead.\n */\nexport const TooltipLink: React.FC<TooltipLinkProps & ThemeOverrideProps> = ({\n children,\n href,\n target,\n rel,\n onPress,\n accent = false,\n underline = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.linkColor ?? theme.colors.content.brand.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n // Mirrors Link: never open a new tab without the reverse-tabnabbing guard.\n const resolvedRel =\n target === \"_blank\"\n ? Array.from(\n new Set([\n ...(rel ? rel.split(/\\s+/).filter(Boolean) : []),\n \"noopener\",\n \"noreferrer\",\n ])\n ).join(\" \")\n : rel;\n\n const handlePress = (event?: any) => {\n if (!onPress) return;\n event?.preventDefault?.();\n onPress();\n };\n\n return (\n <Box\n as=\"a\"\n href={href}\n target={target}\n rel={resolvedRel}\n onPress={handlePress}\n onClick={handlePress}\n role=\"link\"\n cursor=\"pointer\"\n display=\"inline-flex\"\n alignItems=\"center\"\n testID={testID}\n data-testid={dataTestId}\n hoverStyle={{ opacity: 0.8 }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineStyle: \"solid\",\n outlineOffset: 2,\n }}\n >\n <Text\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n textDecoration={underline ? \"underline\" : \"none\"}\n style={{ lineHeight: typo.lineHeight, ...style }}\n >\n {children}\n </Text>\n </Box>\n );\n};\n\nTooltipLink.displayName = \"TooltipLink\";\n"],"mappings":"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","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_jsx_runtime","import_jsx_runtime","import_xui_core","import_jsx_runtime","import_xui_core","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../../src/index.tsx","../../src/Tooltip.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/Portal.native.tsx","../../src/TooltipContentContext.tsx","../../src/contentTypography.ts","../../src/TooltipText.tsx","../../src/TooltipLink.tsx"],"sourcesContent":["export * from \"./Tooltip\";\nexport * from \"./TooltipText\";\nexport * from \"./TooltipLink\";\nexport * from \"./TooltipContentContext\";\nexport * from \"./contentTypography\";\nexport * from \"./types\";\n","import React, { forwardRef, useState, useMemo, useEffect, useRef } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n isNative,\n useModalId,\n useOverlayLayer,\n LAYER_OFFSET,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport type {\n TooltipContentStyles,\n TooltipPlacement,\n TooltipProps,\n TooltipSize,\n} from \"./types\";\nimport { Portal } from \"./Portal\";\nimport { TooltipContentContext } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipTypographyTokens,\n} from \"./contentTypography\";\n\nconst TOOLTIP_OPEN_EVENT = \"xui-tooltip-open\";\ntype TooltipTheme = {\n colors: {\n layer: {\n float: string;\n };\n content: {\n primary: string;\n brand: {\n primary: string;\n };\n };\n };\n shape: {\n tooltip: Record<TooltipSize, { borderRadius: number | string }>;\n };\n typographyTokens?: TooltipTypographyTokens;\n};\n\nconst ARROW_SIZE = 10;\nconst ARROW_HALF = ARROW_SIZE / 2;\n// Keeps the arrow clear of the panel's corner radius (8px for `md`).\nconst ARROW_EDGE_OFFSET = 12;\nconst ARROW_CENTER_INSET = ARROW_EDGE_OFFSET + ARROW_HALF;\n\n// Re-centres the arrow on triggers too narrow for the flush inset (FEP-889).\nconst getArrowAlignmentShift = (triggerWidth: number) =>\n Math.max(0, ARROW_CENTER_INSET - triggerWidth / 2);\n\nconst getPositionStyles = (\n triggerRect: DOMRect,\n placement: TooltipPlacement,\n offset: number,\n isVisible: boolean\n) => {\n const slideDistance = 8;\n const scale = isVisible ? \"scale(1)\" : \"scale(0.95)\";\n const slideOffset = isVisible ? 0 : -slideDistance;\n const arrowShift = getArrowAlignmentShift(triggerRect.width);\n\n switch (placement) {\n case \"top\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-left\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-right\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"bottom\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-left\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-right\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(${slideOffset}px) ${scale}`,\n };\n case \"left\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.left - offset,\n transform: `translateX(calc(-100% - ${slideOffset}px)) translateY(-50%) ${scale}`,\n };\n case \"right\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.right + offset,\n transform: `translateX(${slideOffset}px) translateY(-50%) ${scale}`,\n };\n default:\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n }\n};\n\nconst getArrowStyles = (placement: TooltipPlacement) => {\n const base: React.CSSProperties = {\n width: ARROW_SIZE,\n height: ARROW_SIZE,\n transform: \"rotate(45deg)\",\n borderRadius: 1,\n };\n\n const placementStyles: Record<TooltipPlacement, React.CSSProperties> = {\n top: { bottom: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"top-left\": { bottom: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"top-right\": { bottom: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n bottom: { top: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"bottom-left\": { top: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"bottom-right\": { top: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n left: { right: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n right: { left: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n };\n\n return { ...base, ...placementStyles[placement] };\n};\n\nexport const Tooltip = forwardRef<\n HTMLDivElement,\n TooltipProps & ThemeOverrideProps\n>(\n (\n {\n content,\n children,\n size = \"md\",\n delayEnter = 0,\n delayLeave = 100,\n offset = 12,\n placement = \"top\",\n maxWidth,\n controlledVisible,\n style,\n \"data-testid\": dataTestId,\n className,\n testID,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const [isHovered, setIsHovered] = useState(false);\n const [triggerRect, setTriggerRect] = useState<DOMRect | null>(null);\n const { theme: resolvedTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = resolvedTheme as TooltipTheme;\n const enterTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const leaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rafRef = useRef<number | null>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const tooltipId = useId();\n const modalId = useModalId();\n const overlayLayer = useOverlayLayer();\n\n const isVisible =\n controlledVisible !== undefined ? controlledVisible : isHovered;\n\n const clearPendingVisibilityUpdates = () => {\n if (enterTimeoutRef.current) {\n clearTimeout(enterTimeoutRef.current);\n enterTimeoutRef.current = null;\n }\n\n if (leaveTimeoutRef.current) {\n clearTimeout(leaveTimeoutRef.current);\n leaveTimeoutRef.current = null;\n }\n\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n const forceHideTooltip = () => {\n clearPendingVisibilityUpdates();\n setIsHovered(false);\n };\n\n const positionStyles = useMemo(\n () =>\n triggerRect\n ? getPositionStyles(triggerRect, placement, offset, isVisible)\n : { top: 0, left: 0 },\n [triggerRect, placement, offset, isVisible]\n );\n const typoStyles = useMemo(() => getTooltipTypoStyles(size), [size]);\n const borderRadius = (theme.shape.tooltip[size] ?? theme.shape.tooltip.md)\n .borderRadius;\n const arrowStyles = useMemo(() => getArrowStyles(placement), [placement]);\n\n // Published to arbitrary `content` so nested helpers (TooltipText,\n // TooltipLink) inherit this tooltip's size scale and colour tokens.\n const contentStyles = useMemo<TooltipContentStyles>(\n () => ({\n size,\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n color: theme.colors.content.primary,\n linkColor: theme.colors.content.brand.primary,\n }),\n [\n size,\n typoStyles,\n theme.colors.content.primary,\n theme.colors.content.brand.primary,\n ]\n );\n\n // Update trigger position when tooltip becomes visible and on scroll/resize\n useEffect(() => {\n if (!isVisible || isNative) return;\n\n const updatePosition = () => {\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n }\n };\n\n updatePosition();\n\n window.addEventListener(\"scroll\", updatePosition, true);\n window.addEventListener(\"resize\", updatePosition);\n\n return () => {\n window.removeEventListener(\"scroll\", updatePosition, true);\n window.removeEventListener(\"resize\", updatePosition);\n };\n }, [isVisible]);\n\n const showTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (!isNative && typeof document !== \"undefined\") {\n document.dispatchEvent(\n new CustomEvent(TOOLTIP_OPEN_EVENT, { detail: { tooltipId } })\n );\n }\n\n // Update position before showing to prevent pop-in\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n\n // Double RAF to ensure position is rendered before showing tooltip\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = requestAnimationFrame(() => {\n if (delayEnter > 0) {\n enterTimeoutRef.current = setTimeout(() => {\n setIsHovered(true);\n }, delayEnter);\n } else {\n setIsHovered(true);\n }\n });\n });\n }\n };\n\n const showTooltipOnFocus = (event: React.FocusEvent<HTMLElement>) => {\n // Only reveal the tooltip on intentional keyboard focus. Focus that the\n // browser restores to the trigger when the tab/window regains focus — as\n // well as focus from a mouse click — must not re-trigger the tooltip\n // (FEP-832). `:focus-visible` encodes exactly this heuristic: it matches\n // for keyboard navigation but not for pointer-driven or restored focus.\n const target = event.target as HTMLElement | null;\n\n if (target && typeof target.matches === \"function\") {\n let isFocusVisible: boolean;\n try {\n isFocusVisible = target.matches(\":focus-visible\");\n } catch {\n // Legacy browsers without :focus-visible support — preserve the\n // previous behaviour of showing on any focus.\n isFocusVisible = true;\n }\n\n if (!isFocusVisible) return;\n }\n\n showTooltip();\n };\n\n const hideTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (delayLeave > 0) {\n leaveTimeoutRef.current = setTimeout(() => {\n setIsHovered(false);\n }, delayLeave);\n } else {\n setIsHovered(false);\n }\n };\n\n useEffect(() => {\n if (isNative) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && isVisible) {\n forceHideTooltip();\n }\n };\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") {\n forceHideTooltip();\n }\n };\n\n const handleTooltipOpen = (event: Event) => {\n const { tooltipId: activeTooltipId } =\n (event as CustomEvent).detail ?? {};\n\n if (activeTooltipId !== tooltipId) {\n forceHideTooltip();\n }\n };\n\n document.addEventListener(\"keydown\", handleEscape);\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n document.addEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n\n return () => {\n document.removeEventListener(\"keydown\", handleEscape);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n document.removeEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n clearPendingVisibilityUpdates();\n };\n }, [isVisible, tooltipId]);\n\n return (\n <Box\n testID={testID}\n ref={triggerRef}\n position=\"relative\"\n display=\"inline-flex\"\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n onFocus={showTooltipOnFocus}\n onBlur={hideTooltip}\n className={className}\n style={{ height: \"fit-content\" }}\n aria-describedby={isVisible ? tooltipId : undefined}\n >\n {children}\n {!isNative && triggerRect && (\n <Portal>\n <Box\n ref={ref}\n data-testid={dataTestId}\n data-modal-id={modalId}\n position=\"fixed\"\n backgroundColor={theme.colors.layer.float}\n borderRadius={borderRadius}\n paddingVertical={8}\n paddingHorizontal={12}\n zIndex={overlayLayer + LAYER_OFFSET.tooltip}\n id={tooltipId}\n role=\"tooltip\"\n aria-hidden={!isVisible}\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n style={{\n ...positionStyles,\n // https://stackoverflow.com/questions/62844007/how-to-apply-tool-tip-arrow-triangle-shadow\n filter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n WebkitFilter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? \"visible\" : \"hidden\",\n transition:\n \"opacity 150ms cubic-bezier(.4,0,.2,1), transform 150ms cubic-bezier(.4,0,.2,1), visibility 150ms cubic-bezier(.4,0,.2,1)\",\n pointerEvents: isVisible ? \"auto\" : \"none\",\n whiteSpace: \"normal\",\n width: \"max-content\",\n maxWidth: maxWidth ?? \"none\",\n overflow: \"visible\",\n willChange: isVisible ? \"transform, opacity\" : \"auto\", // optimize rendering and ensure more stable positioning\n ...style,\n }}\n >\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.layer.float}\n style={{\n ...arrowStyles,\n backfaceVisibility: \"hidden\",\n WebkitBackfaceVisibility: \"hidden\",\n }}\n />\n <TooltipContentContext.Provider value={contentStyles}>\n <Box\n style={{\n wordWrap: \"break-word\",\n overflowWrap: \"break-word\",\n maxWidth: \"100%\",\n whiteSpace: \"normal\",\n // Custom `content` inherits the tooltip's own type scale,\n // so plain markup (`<strong>`, `<a>`, bare strings) reads\n // at the right size without re-deriving it per call site.\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n fontWeight: DEFAULT_BODY_FONT_WEIGHT,\n color: theme.colors.content.primary,\n }}\n >\n {typeof content === \"string\" || typeof content === \"number\" ? (\n <Text\n color={theme.colors.content.primary}\n fontSize={typoStyles.fontSize}\n fontWeight={String(DEFAULT_BODY_FONT_WEIGHT)}\n style={{\n lineHeight: typoStyles.lineHeight,\n whiteSpace: \"pre-line\",\n }}\n >\n {content}\n </Text>\n ) : (\n content\n )}\n </Box>\n </TooltipContentContext.Provider>\n </Box>\n </Portal>\n )}\n </Box>\n );\n }\n);\n\nTooltip.displayName = \"Tooltip\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n display,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n display: toNativeDisplay(display),\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import { ReactNode } from \"react\";\n\ninterface PortalProps {\n children: ReactNode;\n}\n\n// Portal not supported on React Native - tooltip content renders inline\nexport const Portal = ({ children }: PortalProps) => {\n return <>{children}</>;\n};\n","import { createContext, useContext } from \"react\";\nimport type { TooltipContentStyles } from \"./types\";\n\n/**\n * Publishes the surrounding tooltip's resolved typography and colour tokens to\n * whatever is rendered inside its `content`, so `TooltipText` / `TooltipLink`\n * inherit the tooltip's size without the caller repeating it.\n *\n * `null` when the consumer is rendered outside a `Tooltip` — the helpers then\n * fall back to their own defaults.\n */\nexport const TooltipContentContext = createContext<TooltipContentStyles | null>(\n null\n);\n\nexport const useTooltipContentStyles = (): TooltipContentStyles | null =>\n useContext(TooltipContentContext);\n","import type { TooltipSize } from \"./types\";\n\n/**\n * Per-size font metrics for tooltip copy. Mirrors the tooltip size matrix in\n * the Figma UI kit (node 5680-32928).\n */\nexport const getTooltipTypoStyles = (size: TooltipSize) => {\n switch (size) {\n case \"sm\":\n return { fontSize: 14, lineHeight: \"16px\" };\n case \"md\":\n return { fontSize: 16, lineHeight: \"18px\" };\n case \"lg\":\n return { fontSize: 18, lineHeight: \"20px\" };\n case \"xl\":\n return { fontSize: 20, lineHeight: \"22px\" };\n default:\n return { fontSize: 16, lineHeight: \"18px\" };\n }\n};\n\n/**\n * Body typography token whose scale matches each tooltip size. Used to resolve\n * the *accent* (bold) font weight for emphasised copy inside a tooltip.\n *\n * `xl` has no body token of its own — the body scale tops out at 18px\n * (`body-lg`) — so it reuses `body-lg`'s accent weight rather than hardcoding\n * a weight the active product context may not use.\n */\nconst TOOLTIP_BODY_VARIANT: Record<TooltipSize, string> = {\n sm: \"body-sm\",\n md: \"body-md\",\n lg: \"body-lg\",\n xl: \"body-lg\",\n};\n\n/** Fallbacks for a resolved theme that predates `typographyTokens`. */\nexport const DEFAULT_BODY_FONT_WEIGHT = 400;\nexport const DEFAULT_ACCENT_FONT_WEIGHT = 500;\n\nexport interface TooltipTypographyTokens {\n basic?: Record<\n string,\n { fontWeight?: number; accent?: { fontWeight?: number } } | undefined\n >;\n}\n\n/** The slice of the resolved theme this module reads. */\nexport interface TooltipThemeTypography {\n typographyTokens?: TooltipTypographyTokens;\n}\n\n/**\n * Resolves the accent font weight for `size` from the theme's body typography\n * scale, so bold tooltip copy follows the active product context (b2b/b2c use\n * 500, corpsite uses 600) instead of a hardcoded weight.\n */\nexport const getTooltipAccentFontWeight = (\n typographyTokens: TooltipTypographyTokens | undefined,\n size: TooltipSize\n): number => {\n const variant = TOOLTIP_BODY_VARIANT[size] ?? TOOLTIP_BODY_VARIANT.md;\n\n return (\n typographyTokens?.basic?.[variant]?.accent?.fontWeight ??\n DEFAULT_ACCENT_FONT_WEIGHT\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipTextProps } from \"./types\";\n\n/**\n * Text inside a `Tooltip`'s `content`, styled with the tooltip's own size\n * scale and `content/primary` colour.\n *\n * Pass `accent` for bold copy — the weight is read from the body accent token\n * matching the tooltip's size, so it tracks the active product context instead\n * of a hardcoded `700`.\n */\nexport const TooltipText: React.FC<TooltipTextProps & ThemeOverrideProps> = ({\n children,\n accent = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.color ?? theme.colors.content.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n return (\n <Text\n testID={testID}\n data-testid={dataTestId}\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n style={{\n lineHeight: typo.lineHeight,\n whiteSpace: \"pre-line\",\n ...style,\n }}\n >\n {children}\n </Text>\n );\n};\n\nTooltipText.displayName = \"TooltipText\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipLinkProps } from \"./types\";\n\n/**\n * A link inside a `Tooltip`'s `content`. Uses the `content/brand-primary`\n * token and the tooltip's own size scale, so it sits inline with surrounding\n * `TooltipText` without the caller re-deriving typography.\n *\n * The tooltip surface is hoverable, so the link is reachable with a pointer.\n * It is **not** reachable by keyboard — tabbing away from the trigger blurs it\n * and dismisses the tooltip. When a link must be keyboard-operable, use\n * [Toggletip](../../toggletip) instead.\n */\nexport const TooltipLink: React.FC<TooltipLinkProps & ThemeOverrideProps> = ({\n children,\n href,\n target,\n rel,\n onPress,\n accent = false,\n underline = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.linkColor ?? theme.colors.content.brand.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n // Mirrors Link: never open a new tab without the reverse-tabnabbing guard.\n const resolvedRel =\n target === \"_blank\"\n ? Array.from(\n new Set([\n ...(rel ? rel.split(/\\s+/).filter(Boolean) : []),\n \"noopener\",\n \"noreferrer\",\n ])\n ).join(\" \")\n : rel;\n\n const handlePress = (event?: any) => {\n if (!onPress) return;\n event?.preventDefault?.();\n onPress();\n };\n\n return (\n <Box\n as=\"a\"\n href={href}\n target={target}\n rel={resolvedRel}\n onPress={handlePress}\n onClick={handlePress}\n role=\"link\"\n cursor=\"pointer\"\n display=\"inline-flex\"\n alignItems=\"center\"\n testID={testID}\n data-testid={dataTestId}\n hoverStyle={{ opacity: 0.8 }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineStyle: \"solid\",\n outlineOffset: 2,\n }}\n >\n <Text\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n textDecoration={underline ? \"underline\" : \"none\"}\n style={{ lineHeight: typo.lineHeight, ...style }}\n >\n {children}\n </Text>\n </Box>\n );\n};\n\nTooltipLink.displayName = \"TooltipLink\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,gBAAwE;;;ACCxE,0BASO;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,IAAAC,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;;;AFjFA,sBAQO;;;AGHE,IAAAC,sBAAA;AADF,IAAM,SAAS,CAAC,EAAE,SAAS,MAAmB;AACnD,SAAO,6EAAG,UAAS;AACrB;;;ACTA,mBAA0C;AAWnC,IAAM,4BAAwB;AAAA,EACnC;AACF;AAEO,IAAM,0BAA0B,UACrC,yBAAW,qBAAqB;;;ACV3B,IAAM,uBAAuB,CAAC,SAAsB;AACzD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C;AACE,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,EAC9C;AACF;AAUA,IAAM,uBAAoD;AAAA,EACxD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAGO,IAAM,2BAA2B;AACjC,IAAM,6BAA6B;AAmBnC,IAAM,6BAA6B,CACxC,kBACA,SACW;AACX,QAAM,UAAU,qBAAqB,IAAI,KAAK,qBAAqB;AAEnE,SACE,kBAAkB,QAAQ,OAAO,GAAG,QAAQ,cAC5C;AAEJ;;;AL4TY,IAAAC,sBAAA;AArWZ,IAAM,qBAAqB;AAmB3B,IAAM,aAAa;AACnB,IAAM,aAAa,aAAa;AAEhC,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB,oBAAoB;AAG/C,IAAM,yBAAyB,CAAC,iBAC9B,KAAK,IAAI,GAAG,qBAAqB,eAAe,CAAC;AAEnD,IAAM,oBAAoB,CACxB,aACA,WACA,QACA,cACG;AACH,QAAM,gBAAgB;AACtB,QAAM,QAAQ,YAAY,aAAa;AACvC,QAAM,cAAc,YAAY,IAAI,CAAC;AACrC,QAAM,aAAa,uBAAuB,YAAY,KAAK;AAE3D,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY,OAAO,YAAY,QAAQ;AAAA,QAC7C,WAAW,4CAA4C,WAAW,QAAQ,KAAK;AAAA,MACjF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY,QAAQ;AAAA,QAC1B,WAAW,6CAA6C,WAAW,QAAQ,KAAK;AAAA,MAClF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY,OAAO;AAAA,QACzB,WAAW,2BAA2B,WAAW,QAAQ,KAAK;AAAA,MAChE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,SAAS;AAAA,QAC1B,MAAM,YAAY,OAAO,YAAY,QAAQ;AAAA,QAC7C,WAAW,+BAA+B,WAAW,OAAO,KAAK;AAAA,MACnE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,SAAS;AAAA,QAC1B,MAAM,YAAY,QAAQ;AAAA,QAC1B,WAAW,gCAAgC,WAAW,OAAO,KAAK;AAAA,MACpE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,SAAS;AAAA,QAC1B,MAAM,YAAY,OAAO;AAAA,QACzB,WAAW,cAAc,WAAW,OAAO,KAAK;AAAA,MAClD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM,YAAY,SAAS;AAAA,QAC5C,MAAM,YAAY,OAAO;AAAA,QACzB,WAAW,2BAA2B,WAAW,yBAAyB,KAAK;AAAA,MACjF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM,YAAY,SAAS;AAAA,QAC5C,MAAM,YAAY,QAAQ;AAAA,QAC1B,WAAW,cAAc,WAAW,wBAAwB,KAAK;AAAA,MACnE;AAAA,IACF;AACE,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY;AAAA,QAClB,WAAW,2BAA2B,WAAW,QAAQ,KAAK;AAAA,MAChE;AAAA,EACJ;AACF;AAEA,IAAM,iBAAiB,CAAC,cAAgC;AACtD,QAAM,OAA4B;AAAA,IAChC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,cAAc;AAAA,EAChB;AAEA,QAAM,kBAAiE;AAAA,IACrE,KAAK,EAAE,QAAQ,CAAC,YAAY,MAAM,OAAO,YAAY,CAAC,WAAW;AAAA,IACjE,YAAY,EAAE,QAAQ,CAAC,YAAY,OAAO,kBAAkB;AAAA,IAC5D,aAAa,EAAE,QAAQ,CAAC,YAAY,MAAM,kBAAkB;AAAA,IAE5D,QAAQ,EAAE,KAAK,CAAC,YAAY,MAAM,OAAO,YAAY,CAAC,WAAW;AAAA,IACjE,eAAe,EAAE,KAAK,CAAC,YAAY,OAAO,kBAAkB;AAAA,IAC5D,gBAAgB,EAAE,KAAK,CAAC,YAAY,MAAM,kBAAkB;AAAA,IAE5D,MAAM,EAAE,OAAO,CAAC,YAAY,KAAK,OAAO,WAAW,CAAC,WAAW;AAAA,IAC/D,OAAO,EAAE,MAAM,CAAC,YAAY,KAAK,OAAO,WAAW,CAAC,WAAW;AAAA,EACjE;AAEA,SAAO,EAAE,GAAG,MAAM,GAAG,gBAAgB,SAAS,EAAE;AAClD;AAEO,IAAM,cAAU;AAAA,EAIrB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACA,QACG;AACH,UAAM,CAAC,WAAW,YAAY,QAAI,wBAAS,KAAK;AAChD,UAAM,CAAC,aAAa,cAAc,QAAI,wBAAyB,IAAI;AACnE,UAAM,EAAE,OAAO,cAAc,QAAI,kCAAiB;AAAA,MAChD;AAAA,MACA;AAAA,IACF,CAAC;AACD,UAAM,QAAQ;AACd,UAAM,sBAAkB,sBAA6C,IAAI;AACzE,UAAM,sBAAkB,sBAA6C,IAAI;AACzE,UAAM,aAAS,sBAAsB,IAAI;AACzC,UAAM,iBAAa,sBAAuB,IAAI;AAC9C,UAAM,gBAAY,uBAAM;AACxB,UAAM,cAAU,4BAAW;AAC3B,UAAM,mBAAe,iCAAgB;AAErC,UAAM,YACJ,sBAAsB,SAAY,oBAAoB;AAExD,UAAM,gCAAgC,MAAM;AAC1C,UAAI,gBAAgB,SAAS;AAC3B,qBAAa,gBAAgB,OAAO;AACpC,wBAAgB,UAAU;AAAA,MAC5B;AAEA,UAAI,gBAAgB,SAAS;AAC3B,qBAAa,gBAAgB,OAAO;AACpC,wBAAgB,UAAU;AAAA,MAC5B;AAEA,UAAI,OAAO,SAAS;AAClB,6BAAqB,OAAO,OAAO;AACnC,eAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,mBAAmB,MAAM;AAC7B,oCAA8B;AAC9B,mBAAa,KAAK;AAAA,IACpB;AAEA,UAAM,qBAAiB;AAAA,MACrB,MACE,cACI,kBAAkB,aAAa,WAAW,QAAQ,SAAS,IAC3D,EAAE,KAAK,GAAG,MAAM,EAAE;AAAA,MACxB,CAAC,aAAa,WAAW,QAAQ,SAAS;AAAA,IAC5C;AACA,UAAM,iBAAa,uBAAQ,MAAM,qBAAqB,IAAI,GAAG,CAAC,IAAI,CAAC;AACnE,UAAM,gBAAgB,MAAM,MAAM,QAAQ,IAAI,KAAK,MAAM,MAAM,QAAQ,IACpE;AACH,UAAM,kBAAc,uBAAQ,MAAM,eAAe,SAAS,GAAG,CAAC,SAAS,CAAC;AAIxE,UAAM,oBAAgB;AAAA,MACpB,OAAO;AAAA,QACL;AAAA,QACA,UAAU,WAAW;AAAA,QACrB,YAAY,WAAW;AAAA,QACvB,OAAO,MAAM,OAAO,QAAQ;AAAA,QAC5B,WAAW,MAAM,OAAO,QAAQ,MAAM;AAAA,MACxC;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,MAAM,OAAO,QAAQ;AAAA,QACrB,MAAM,OAAO,QAAQ,MAAM;AAAA,MAC7B;AAAA,IACF;AAGA,iCAAU,MAAM;AACd,UAAI,CAAC,aAAa,yBAAU;AAE5B,YAAM,iBAAiB,MAAM;AAC3B,YAAI,WAAW,SAAS;AACtB,yBAAe,WAAW,QAAQ,sBAAsB,CAAC;AAAA,QAC3D;AAAA,MACF;AAEA,qBAAe;AAEf,aAAO,iBAAiB,UAAU,gBAAgB,IAAI;AACtD,aAAO,iBAAiB,UAAU,cAAc;AAEhD,aAAO,MAAM;AACX,eAAO,oBAAoB,UAAU,gBAAgB,IAAI;AACzD,eAAO,oBAAoB,UAAU,cAAc;AAAA,MACrD;AAAA,IACF,GAAG,CAAC,SAAS,CAAC;AAEd,UAAM,cAAc,MAAM;AACxB,oCAA8B;AAE9B,UAAI,CAAC,4BAAY,OAAO,aAAa,aAAa;AAChD,iBAAS;AAAA,UACP,IAAI,YAAY,oBAAoB,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAAA,QAC/D;AAAA,MACF;AAGA,UAAI,WAAW,SAAS;AACtB,uBAAe,WAAW,QAAQ,sBAAsB,CAAC;AAGzD,eAAO,UAAU,sBAAsB,MAAM;AAC3C,iBAAO,UAAU,sBAAsB,MAAM;AAC3C,gBAAI,aAAa,GAAG;AAClB,8BAAgB,UAAU,WAAW,MAAM;AACzC,6BAAa,IAAI;AAAA,cACnB,GAAG,UAAU;AAAA,YACf,OAAO;AACL,2BAAa,IAAI;AAAA,YACnB;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,qBAAqB,CAAC,UAAyC;AAMnE,YAAM,SAAS,MAAM;AAErB,UAAI,UAAU,OAAO,OAAO,YAAY,YAAY;AAClD,YAAI;AACJ,YAAI;AACF,2BAAiB,OAAO,QAAQ,gBAAgB;AAAA,QAClD,QAAQ;AAGN,2BAAiB;AAAA,QACnB;AAEA,YAAI,CAAC,eAAgB;AAAA,MACvB;AAEA,kBAAY;AAAA,IACd;AAEA,UAAM,cAAc,MAAM;AACxB,oCAA8B;AAE9B,UAAI,aAAa,GAAG;AAClB,wBAAgB,UAAU,WAAW,MAAM;AACzC,uBAAa,KAAK;AAAA,QACpB,GAAG,UAAU;AAAA,MACf,OAAO;AACL,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,iCAAU,MAAM;AACd,UAAI,yBAAU;AAEd,YAAM,eAAe,CAAC,UAAyB;AAC7C,YAAI,MAAM,QAAQ,YAAY,WAAW;AACvC,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,YAAM,yBAAyB,MAAM;AACnC,YAAI,SAAS,oBAAoB,UAAU;AACzC,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,YAAM,oBAAoB,CAAC,UAAiB;AAC1C,cAAM,EAAE,WAAW,gBAAgB,IAChC,MAAsB,UAAU,CAAC;AAEpC,YAAI,oBAAoB,WAAW;AACjC,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,eAAS,iBAAiB,WAAW,YAAY;AACjD,eAAS,iBAAiB,oBAAoB,sBAAsB;AACpE,eAAS,iBAAiB,oBAAoB,iBAAiB;AAE/D,aAAO,MAAM;AACX,iBAAS,oBAAoB,WAAW,YAAY;AACpD,iBAAS;AAAA,UACP;AAAA,UACA;AAAA,QACF;AACA,iBAAS,oBAAoB,oBAAoB,iBAAiB;AAClE,sCAA8B;AAAA,MAChC;AAAA,IACF,GAAG,CAAC,WAAW,SAAS,CAAC;AAEzB,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL,UAAS;AAAA,QACT,SAAQ;AAAA,QACR,cAAc;AAAA,QACd,cAAc;AAAA,QACd,SAAS;AAAA,QACT,QAAQ;AAAA,QACR;AAAA,QACA,OAAO,EAAE,QAAQ,cAAc;AAAA,QAC/B,oBAAkB,YAAY,YAAY;AAAA,QAEzC;AAAA;AAAA,UACA,CAAC,4BAAY,eACZ,6CAAC,UACC;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,eAAa;AAAA,cACb,iBAAe;AAAA,cACf,UAAS;AAAA,cACT,iBAAiB,MAAM,OAAO,MAAM;AAAA,cACpC;AAAA,cACA,iBAAiB;AAAA,cACjB,mBAAmB;AAAA,cACnB,QAAQ,eAAe,6BAAa;AAAA,cACpC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,eAAa,CAAC;AAAA,cACd,cAAc;AAAA,cACd,cAAc;AAAA,cACd,OAAO;AAAA,gBACL,GAAG;AAAA;AAAA,gBAEH,QACE;AAAA,gBACF,cACE;AAAA,gBACF,SAAS,YAAY,IAAI;AAAA,gBACzB,YAAY,YAAY,YAAY;AAAA,gBACpC,YACE;AAAA,gBACF,eAAe,YAAY,SAAS;AAAA,gBACpC,YAAY;AAAA,gBACZ,OAAO;AAAA,gBACP,UAAU,YAAY;AAAA,gBACtB,UAAU;AAAA,gBACV,YAAY,YAAY,uBAAuB;AAAA;AAAA,gBAC/C,GAAG;AAAA,cACL;AAAA,cAEA;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,UAAS;AAAA,oBACT,iBAAiB,MAAM,OAAO,MAAM;AAAA,oBACpC,OAAO;AAAA,sBACL,GAAG;AAAA,sBACH,oBAAoB;AAAA,sBACpB,0BAA0B;AAAA,oBAC5B;AAAA;AAAA,gBACF;AAAA,gBACA,6CAAC,sBAAsB,UAAtB,EAA+B,OAAO,eACrC;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,cAAc;AAAA,sBACd,UAAU;AAAA,sBACV,YAAY;AAAA;AAAA;AAAA;AAAA,sBAIZ,UAAU,WAAW;AAAA,sBACrB,YAAY,WAAW;AAAA,sBACvB,YAAY;AAAA,sBACZ,OAAO,MAAM,OAAO,QAAQ;AAAA,oBAC9B;AAAA,oBAEC,iBAAO,YAAY,YAAY,OAAO,YAAY,WACjD;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO,MAAM,OAAO,QAAQ;AAAA,wBAC5B,UAAU,WAAW;AAAA,wBACrB,YAAY,OAAO,wBAAwB;AAAA,wBAC3C,OAAO;AAAA,0BACL,YAAY,WAAW;AAAA,0BACvB,YAAY;AAAA,wBACd;AAAA,wBAEC;AAAA;AAAA,oBACH,IAEA;AAAA;AAAA,gBAEJ,GACF;AAAA;AAAA;AAAA,UACF,GACF;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,QAAQ,cAAc;;;AMjdtB,IAAAC,mBAA0D;AA4CtD,IAAAC,sBAAA;AA1BG,IAAM,cAA+D,CAAC;AAAA,EAC3E;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AACF,MAAM;AACJ,QAAM,YAAY,wBAAwB;AAC1C,QAAM,EAAE,MAAM,QAAI,mCAAiB,EAAE,WAAW,oBAAoB,CAAC;AAErE,QAAM,eAAe,QAAQ,WAAW,QAAQ;AAChD,QAAM,OAAO,qBAAqB,YAAY;AAC9C,QAAM,gBACJ,SAAS,WAAW,SAAS,MAAM,OAAO,QAAQ;AACpD,QAAM,aAAa,SACf;AAAA,IACG,MAA4C;AAAA,IAC7C;AAAA,EACF,IACA;AAEJ,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MACb,OAAO;AAAA,MACP,UAAU,KAAK;AAAA,MACf,YAAY,OAAO,UAAU;AAAA,MAC7B,OAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,YAAY;AAAA,QACZ,GAAG;AAAA,MACL;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEA,YAAY,cAAc;;;AC7D1B,IAAAC,mBAA0D;AA0FpD,IAAAC,sBAAA;AAtEC,IAAM,cAA+D,CAAC;AAAA,EAC3E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AACF,MAAM;AACJ,QAAM,YAAY,wBAAwB;AAC1C,QAAM,EAAE,MAAM,QAAI,mCAAiB,EAAE,WAAW,oBAAoB,CAAC;AAErE,QAAM,eAAe,QAAQ,WAAW,QAAQ;AAChD,QAAM,OAAO,qBAAqB,YAAY;AAC9C,QAAM,gBACJ,SAAS,WAAW,aAAa,MAAM,OAAO,QAAQ,MAAM;AAC9D,QAAM,aAAa,SACf;AAAA,IACG,MAA4C;AAAA,IAC7C;AAAA,EACF,IACA;AAGJ,QAAM,cACJ,WAAW,WACP,MAAM;AAAA,IACJ,oBAAI,IAAI;AAAA,MACN,GAAI,MAAM,IAAI,MAAM,KAAK,EAAE,OAAO,OAAO,IAAI,CAAC;AAAA,MAC9C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,EAAE,KAAK,GAAG,IACV;AAEN,QAAM,cAAc,CAAC,UAAgB;AACnC,QAAI,CAAC,QAAS;AACd,WAAO,iBAAiB;AACxB,YAAQ;AAAA,EACV;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAK;AAAA,MACL,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,YAAW;AAAA,MACX;AAAA,MACA,eAAa;AAAA,MACb,YAAY,EAAE,SAAS,IAAI;AAAA,MAC3B,YAAY;AAAA,QACV,cAAc,MAAM,OAAO,OAAO;AAAA,QAClC,cAAc;AAAA,QACd,cAAc;AAAA,QACd,eAAe;AAAA,MACjB;AAAA,MAEA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU,KAAK;AAAA,UACf,YAAY,OAAO,UAAU;AAAA,UAC7B,gBAAgB,YAAY,cAAc;AAAA,UAC1C,OAAO,EAAE,YAAY,KAAK,YAAY,GAAG,MAAM;AAAA,UAE9C;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAEA,YAAY,cAAc;","names":["import_react","import_react_native","import_jsx_runtime","RNText","import_jsx_runtime","import_jsx_runtime","import_xui_core","import_jsx_runtime","import_xui_core","import_jsx_runtime"]}
|
package/native/index.mjs
CHANGED
|
@@ -40,6 +40,7 @@ var toGapValue = (gap) => {
|
|
|
40
40
|
const asNumber = Number(gap);
|
|
41
41
|
return Number.isFinite(asNumber) ? asNumber : void 0;
|
|
42
42
|
};
|
|
43
|
+
var toNativeDisplay = (display) => display === "none" ? "none" : void 0;
|
|
43
44
|
var Box = ({
|
|
44
45
|
children,
|
|
45
46
|
onPress,
|
|
@@ -71,6 +72,7 @@ var Box = ({
|
|
|
71
72
|
marginBottom,
|
|
72
73
|
marginLeft,
|
|
73
74
|
marginRight,
|
|
75
|
+
display,
|
|
74
76
|
flexDirection,
|
|
75
77
|
flexWrap,
|
|
76
78
|
alignItems,
|
|
@@ -134,6 +136,7 @@ var Box = ({
|
|
|
134
136
|
marginBottom,
|
|
135
137
|
marginLeft,
|
|
136
138
|
marginRight,
|
|
139
|
+
display: toNativeDisplay(display),
|
|
137
140
|
flexDirection,
|
|
138
141
|
flexWrap,
|
|
139
142
|
alignItems,
|
package/native/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/Tooltip.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/Portal.native.tsx","../../src/TooltipContentContext.tsx","../../src/contentTypography.ts","../../src/TooltipText.tsx","../../src/TooltipLink.tsx"],"sourcesContent":["import React, { forwardRef, useState, useMemo, useEffect, useRef } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n isNative,\n useModalId,\n useOverlayLayer,\n LAYER_OFFSET,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport type {\n TooltipContentStyles,\n TooltipPlacement,\n TooltipProps,\n TooltipSize,\n} from \"./types\";\nimport { Portal } from \"./Portal\";\nimport { TooltipContentContext } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipTypographyTokens,\n} from \"./contentTypography\";\n\nconst TOOLTIP_OPEN_EVENT = \"xui-tooltip-open\";\ntype TooltipTheme = {\n colors: {\n layer: {\n float: string;\n };\n content: {\n primary: string;\n brand: {\n primary: string;\n };\n };\n };\n shape: {\n tooltip: Record<TooltipSize, { borderRadius: number | string }>;\n };\n typographyTokens?: TooltipTypographyTokens;\n};\n\nconst ARROW_SIZE = 10;\nconst ARROW_HALF = ARROW_SIZE / 2;\n// Keeps the arrow clear of the panel's corner radius (8px for `md`).\nconst ARROW_EDGE_OFFSET = 12;\nconst ARROW_CENTER_INSET = ARROW_EDGE_OFFSET + ARROW_HALF;\n\n// Re-centres the arrow on triggers too narrow for the flush inset (FEP-889).\nconst getArrowAlignmentShift = (triggerWidth: number) =>\n Math.max(0, ARROW_CENTER_INSET - triggerWidth / 2);\n\nconst getPositionStyles = (\n triggerRect: DOMRect,\n placement: TooltipPlacement,\n offset: number,\n isVisible: boolean\n) => {\n const slideDistance = 8;\n const scale = isVisible ? \"scale(1)\" : \"scale(0.95)\";\n const slideOffset = isVisible ? 0 : -slideDistance;\n const arrowShift = getArrowAlignmentShift(triggerRect.width);\n\n switch (placement) {\n case \"top\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-left\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-right\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"bottom\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-left\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-right\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(${slideOffset}px) ${scale}`,\n };\n case \"left\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.left - offset,\n transform: `translateX(calc(-100% - ${slideOffset}px)) translateY(-50%) ${scale}`,\n };\n case \"right\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.right + offset,\n transform: `translateX(${slideOffset}px) translateY(-50%) ${scale}`,\n };\n default:\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n }\n};\n\nconst getArrowStyles = (placement: TooltipPlacement) => {\n const base: React.CSSProperties = {\n width: ARROW_SIZE,\n height: ARROW_SIZE,\n transform: \"rotate(45deg)\",\n borderRadius: 1,\n };\n\n const placementStyles: Record<TooltipPlacement, React.CSSProperties> = {\n top: { bottom: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"top-left\": { bottom: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"top-right\": { bottom: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n bottom: { top: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"bottom-left\": { top: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"bottom-right\": { top: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n left: { right: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n right: { left: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n };\n\n return { ...base, ...placementStyles[placement] };\n};\n\nexport const Tooltip = forwardRef<\n HTMLDivElement,\n TooltipProps & ThemeOverrideProps\n>(\n (\n {\n content,\n children,\n size = \"md\",\n delayEnter = 0,\n delayLeave = 100,\n offset = 12,\n placement = \"top\",\n maxWidth,\n controlledVisible,\n style,\n \"data-testid\": dataTestId,\n className,\n testID,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const [isHovered, setIsHovered] = useState(false);\n const [triggerRect, setTriggerRect] = useState<DOMRect | null>(null);\n const { theme: resolvedTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = resolvedTheme as TooltipTheme;\n const enterTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const leaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rafRef = useRef<number | null>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const tooltipId = useId();\n const modalId = useModalId();\n const overlayLayer = useOverlayLayer();\n\n const isVisible =\n controlledVisible !== undefined ? controlledVisible : isHovered;\n\n const clearPendingVisibilityUpdates = () => {\n if (enterTimeoutRef.current) {\n clearTimeout(enterTimeoutRef.current);\n enterTimeoutRef.current = null;\n }\n\n if (leaveTimeoutRef.current) {\n clearTimeout(leaveTimeoutRef.current);\n leaveTimeoutRef.current = null;\n }\n\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n const forceHideTooltip = () => {\n clearPendingVisibilityUpdates();\n setIsHovered(false);\n };\n\n const positionStyles = useMemo(\n () =>\n triggerRect\n ? getPositionStyles(triggerRect, placement, offset, isVisible)\n : { top: 0, left: 0 },\n [triggerRect, placement, offset, isVisible]\n );\n const typoStyles = useMemo(() => getTooltipTypoStyles(size), [size]);\n const borderRadius = (theme.shape.tooltip[size] ?? theme.shape.tooltip.md)\n .borderRadius;\n const arrowStyles = useMemo(() => getArrowStyles(placement), [placement]);\n\n // Published to arbitrary `content` so nested helpers (TooltipText,\n // TooltipLink) inherit this tooltip's size scale and colour tokens.\n const contentStyles = useMemo<TooltipContentStyles>(\n () => ({\n size,\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n color: theme.colors.content.primary,\n linkColor: theme.colors.content.brand.primary,\n }),\n [\n size,\n typoStyles,\n theme.colors.content.primary,\n theme.colors.content.brand.primary,\n ]\n );\n\n // Update trigger position when tooltip becomes visible and on scroll/resize\n useEffect(() => {\n if (!isVisible || isNative) return;\n\n const updatePosition = () => {\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n }\n };\n\n updatePosition();\n\n window.addEventListener(\"scroll\", updatePosition, true);\n window.addEventListener(\"resize\", updatePosition);\n\n return () => {\n window.removeEventListener(\"scroll\", updatePosition, true);\n window.removeEventListener(\"resize\", updatePosition);\n };\n }, [isVisible]);\n\n const showTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (!isNative && typeof document !== \"undefined\") {\n document.dispatchEvent(\n new CustomEvent(TOOLTIP_OPEN_EVENT, { detail: { tooltipId } })\n );\n }\n\n // Update position before showing to prevent pop-in\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n\n // Double RAF to ensure position is rendered before showing tooltip\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = requestAnimationFrame(() => {\n if (delayEnter > 0) {\n enterTimeoutRef.current = setTimeout(() => {\n setIsHovered(true);\n }, delayEnter);\n } else {\n setIsHovered(true);\n }\n });\n });\n }\n };\n\n const showTooltipOnFocus = (event: React.FocusEvent<HTMLElement>) => {\n // Only reveal the tooltip on intentional keyboard focus. Focus that the\n // browser restores to the trigger when the tab/window regains focus — as\n // well as focus from a mouse click — must not re-trigger the tooltip\n // (FEP-832). `:focus-visible` encodes exactly this heuristic: it matches\n // for keyboard navigation but not for pointer-driven or restored focus.\n const target = event.target as HTMLElement | null;\n\n if (target && typeof target.matches === \"function\") {\n let isFocusVisible: boolean;\n try {\n isFocusVisible = target.matches(\":focus-visible\");\n } catch {\n // Legacy browsers without :focus-visible support — preserve the\n // previous behaviour of showing on any focus.\n isFocusVisible = true;\n }\n\n if (!isFocusVisible) return;\n }\n\n showTooltip();\n };\n\n const hideTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (delayLeave > 0) {\n leaveTimeoutRef.current = setTimeout(() => {\n setIsHovered(false);\n }, delayLeave);\n } else {\n setIsHovered(false);\n }\n };\n\n useEffect(() => {\n if (isNative) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && isVisible) {\n forceHideTooltip();\n }\n };\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") {\n forceHideTooltip();\n }\n };\n\n const handleTooltipOpen = (event: Event) => {\n const { tooltipId: activeTooltipId } =\n (event as CustomEvent).detail ?? {};\n\n if (activeTooltipId !== tooltipId) {\n forceHideTooltip();\n }\n };\n\n document.addEventListener(\"keydown\", handleEscape);\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n document.addEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n\n return () => {\n document.removeEventListener(\"keydown\", handleEscape);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n document.removeEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n clearPendingVisibilityUpdates();\n };\n }, [isVisible, tooltipId]);\n\n return (\n <Box\n testID={testID}\n ref={triggerRef}\n position=\"relative\"\n display=\"inline-flex\"\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n onFocus={showTooltipOnFocus}\n onBlur={hideTooltip}\n className={className}\n style={{ height: \"fit-content\" }}\n aria-describedby={isVisible ? tooltipId : undefined}\n >\n {children}\n {!isNative && triggerRect && (\n <Portal>\n <Box\n ref={ref}\n data-testid={dataTestId}\n data-modal-id={modalId}\n position=\"fixed\"\n backgroundColor={theme.colors.layer.float}\n borderRadius={borderRadius}\n paddingVertical={8}\n paddingHorizontal={12}\n zIndex={overlayLayer + LAYER_OFFSET.tooltip}\n id={tooltipId}\n role=\"tooltip\"\n aria-hidden={!isVisible}\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n style={{\n ...positionStyles,\n // https://stackoverflow.com/questions/62844007/how-to-apply-tool-tip-arrow-triangle-shadow\n filter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n WebkitFilter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? \"visible\" : \"hidden\",\n transition:\n \"opacity 150ms cubic-bezier(.4,0,.2,1), transform 150ms cubic-bezier(.4,0,.2,1), visibility 150ms cubic-bezier(.4,0,.2,1)\",\n pointerEvents: isVisible ? \"auto\" : \"none\",\n whiteSpace: \"normal\",\n width: \"max-content\",\n maxWidth: maxWidth ?? \"none\",\n overflow: \"visible\",\n willChange: isVisible ? \"transform, opacity\" : \"auto\", // optimize rendering and ensure more stable positioning\n ...style,\n }}\n >\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.layer.float}\n style={{\n ...arrowStyles,\n backfaceVisibility: \"hidden\",\n WebkitBackfaceVisibility: \"hidden\",\n }}\n />\n <TooltipContentContext.Provider value={contentStyles}>\n <Box\n style={{\n wordWrap: \"break-word\",\n overflowWrap: \"break-word\",\n maxWidth: \"100%\",\n whiteSpace: \"normal\",\n // Custom `content` inherits the tooltip's own type scale,\n // so plain markup (`<strong>`, `<a>`, bare strings) reads\n // at the right size without re-deriving it per call site.\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n fontWeight: DEFAULT_BODY_FONT_WEIGHT,\n color: theme.colors.content.primary,\n }}\n >\n {typeof content === \"string\" || typeof content === \"number\" ? (\n <Text\n color={theme.colors.content.primary}\n fontSize={typoStyles.fontSize}\n fontWeight={String(DEFAULT_BODY_FONT_WEIGHT)}\n style={{\n lineHeight: typoStyles.lineHeight,\n whiteSpace: \"pre-line\",\n }}\n >\n {content}\n </Text>\n ) : (\n content\n )}\n </Box>\n </TooltipContentContext.Provider>\n </Box>\n </Portal>\n )}\n </Box>\n );\n }\n);\n\nTooltip.displayName = \"Tooltip\";\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","import { ReactNode } from \"react\";\n\ninterface PortalProps {\n children: ReactNode;\n}\n\n// Portal not supported on React Native - tooltip content renders inline\nexport const Portal = ({ children }: PortalProps) => {\n return <>{children}</>;\n};\n","import { createContext, useContext } from \"react\";\nimport type { TooltipContentStyles } from \"./types\";\n\n/**\n * Publishes the surrounding tooltip's resolved typography and colour tokens to\n * whatever is rendered inside its `content`, so `TooltipText` / `TooltipLink`\n * inherit the tooltip's size without the caller repeating it.\n *\n * `null` when the consumer is rendered outside a `Tooltip` — the helpers then\n * fall back to their own defaults.\n */\nexport const TooltipContentContext = createContext<TooltipContentStyles | null>(\n null\n);\n\nexport const useTooltipContentStyles = (): TooltipContentStyles | null =>\n useContext(TooltipContentContext);\n","import type { TooltipSize } from \"./types\";\n\n/**\n * Per-size font metrics for tooltip copy. Mirrors the tooltip size matrix in\n * the Figma UI kit (node 5680-32928).\n */\nexport const getTooltipTypoStyles = (size: TooltipSize) => {\n switch (size) {\n case \"sm\":\n return { fontSize: 14, lineHeight: \"16px\" };\n case \"md\":\n return { fontSize: 16, lineHeight: \"18px\" };\n case \"lg\":\n return { fontSize: 18, lineHeight: \"20px\" };\n case \"xl\":\n return { fontSize: 20, lineHeight: \"22px\" };\n default:\n return { fontSize: 16, lineHeight: \"18px\" };\n }\n};\n\n/**\n * Body typography token whose scale matches each tooltip size. Used to resolve\n * the *accent* (bold) font weight for emphasised copy inside a tooltip.\n *\n * `xl` has no body token of its own — the body scale tops out at 18px\n * (`body-lg`) — so it reuses `body-lg`'s accent weight rather than hardcoding\n * a weight the active product context may not use.\n */\nconst TOOLTIP_BODY_VARIANT: Record<TooltipSize, string> = {\n sm: \"body-sm\",\n md: \"body-md\",\n lg: \"body-lg\",\n xl: \"body-lg\",\n};\n\n/** Fallbacks for a resolved theme that predates `typographyTokens`. */\nexport const DEFAULT_BODY_FONT_WEIGHT = 400;\nexport const DEFAULT_ACCENT_FONT_WEIGHT = 500;\n\nexport interface TooltipTypographyTokens {\n basic?: Record<\n string,\n { fontWeight?: number; accent?: { fontWeight?: number } } | undefined\n >;\n}\n\n/** The slice of the resolved theme this module reads. */\nexport interface TooltipThemeTypography {\n typographyTokens?: TooltipTypographyTokens;\n}\n\n/**\n * Resolves the accent font weight for `size` from the theme's body typography\n * scale, so bold tooltip copy follows the active product context (b2b/b2c use\n * 500, corpsite uses 600) instead of a hardcoded weight.\n */\nexport const getTooltipAccentFontWeight = (\n typographyTokens: TooltipTypographyTokens | undefined,\n size: TooltipSize\n): number => {\n const variant = TOOLTIP_BODY_VARIANT[size] ?? TOOLTIP_BODY_VARIANT.md;\n\n return (\n typographyTokens?.basic?.[variant]?.accent?.fontWeight ??\n DEFAULT_ACCENT_FONT_WEIGHT\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipTextProps } from \"./types\";\n\n/**\n * Text inside a `Tooltip`'s `content`, styled with the tooltip's own size\n * scale and `content/primary` colour.\n *\n * Pass `accent` for bold copy — the weight is read from the body accent token\n * matching the tooltip's size, so it tracks the active product context instead\n * of a hardcoded `700`.\n */\nexport const TooltipText: React.FC<TooltipTextProps & ThemeOverrideProps> = ({\n children,\n accent = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.color ?? theme.colors.content.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n return (\n <Text\n testID={testID}\n data-testid={dataTestId}\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n style={{\n lineHeight: typo.lineHeight,\n whiteSpace: \"pre-line\",\n ...style,\n }}\n >\n {children}\n </Text>\n );\n};\n\nTooltipText.displayName = \"TooltipText\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipLinkProps } from \"./types\";\n\n/**\n * A link inside a `Tooltip`'s `content`. Uses the `content/brand-primary`\n * token and the tooltip's own size scale, so it sits inline with surrounding\n * `TooltipText` without the caller re-deriving typography.\n *\n * The tooltip surface is hoverable, so the link is reachable with a pointer.\n * It is **not** reachable by keyboard — tabbing away from the trigger blurs it\n * and dismisses the tooltip. When a link must be keyboard-operable, use\n * [Toggletip](../../toggletip) instead.\n */\nexport const TooltipLink: React.FC<TooltipLinkProps & ThemeOverrideProps> = ({\n children,\n href,\n target,\n rel,\n onPress,\n accent = false,\n underline = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.linkColor ?? theme.colors.content.brand.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n // Mirrors Link: never open a new tab without the reverse-tabnabbing guard.\n const resolvedRel =\n target === \"_blank\"\n ? Array.from(\n new Set([\n ...(rel ? rel.split(/\\s+/).filter(Boolean) : []),\n \"noopener\",\n \"noreferrer\",\n ])\n ).join(\" \")\n : rel;\n\n const handlePress = (event?: any) => {\n if (!onPress) return;\n event?.preventDefault?.();\n onPress();\n };\n\n return (\n <Box\n as=\"a\"\n href={href}\n target={target}\n rel={resolvedRel}\n onPress={handlePress}\n onClick={handlePress}\n role=\"link\"\n cursor=\"pointer\"\n display=\"inline-flex\"\n alignItems=\"center\"\n testID={testID}\n data-testid={dataTestId}\n hoverStyle={{ opacity: 0.8 }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineStyle: \"solid\",\n outlineOffset: 2,\n }}\n >\n <Text\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n textDecoration={underline ? \"underline\" : \"none\"}\n style={{ lineHeight: typo.lineHeight, ...style }}\n >\n {children}\n </Text>\n </Box>\n );\n};\n\nTooltipLink.displayName = \"TooltipLink\";\n"],"mappings":";AAAA,SAAgB,YAAY,UAAU,SAAS,WAAW,cAAc;;;ACCxE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAMK;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;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;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;;;AGHE,0BAAAC,YAAA;AADF,IAAM,SAAS,CAAC,EAAE,SAAS,MAAmB;AACnD,SAAO,gBAAAA,KAAA,YAAG,UAAS;AACrB;;;ACTA,SAAS,eAAe,kBAAkB;AAWnC,IAAM,wBAAwB;AAAA,EACnC;AACF;AAEO,IAAM,0BAA0B,MACrC,WAAW,qBAAqB;;;ACV3B,IAAM,uBAAuB,CAAC,SAAsB;AACzD,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C,KAAK;AACH,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,IAC5C;AACE,aAAO,EAAE,UAAU,IAAI,YAAY,OAAO;AAAA,EAC9C;AACF;AAUA,IAAM,uBAAoD;AAAA,EACxD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAGO,IAAM,2BAA2B;AACjC,IAAM,6BAA6B;AAmBnC,IAAM,6BAA6B,CACxC,kBACA,SACW;AACX,QAAM,UAAU,qBAAqB,IAAI,KAAK,qBAAqB;AAEnE,SACE,kBAAkB,QAAQ,OAAO,GAAG,QAAQ,cAC5C;AAEJ;;;AL4TY,SAmCE,OAAAC,MAnCF;AArWZ,IAAM,qBAAqB;AAmB3B,IAAM,aAAa;AACnB,IAAM,aAAa,aAAa;AAEhC,IAAM,oBAAoB;AAC1B,IAAM,qBAAqB,oBAAoB;AAG/C,IAAM,yBAAyB,CAAC,iBAC9B,KAAK,IAAI,GAAG,qBAAqB,eAAe,CAAC;AAEnD,IAAM,oBAAoB,CACxB,aACA,WACA,QACA,cACG;AACH,QAAM,gBAAgB;AACtB,QAAM,QAAQ,YAAY,aAAa;AACvC,QAAM,cAAc,YAAY,IAAI,CAAC;AACrC,QAAM,aAAa,uBAAuB,YAAY,KAAK;AAE3D,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY,OAAO,YAAY,QAAQ;AAAA,QAC7C,WAAW,4CAA4C,WAAW,QAAQ,KAAK;AAAA,MACjF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY,QAAQ;AAAA,QAC1B,WAAW,6CAA6C,WAAW,QAAQ,KAAK;AAAA,MAClF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY,OAAO;AAAA,QACzB,WAAW,2BAA2B,WAAW,QAAQ,KAAK;AAAA,MAChE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,SAAS;AAAA,QAC1B,MAAM,YAAY,OAAO,YAAY,QAAQ;AAAA,QAC7C,WAAW,+BAA+B,WAAW,OAAO,KAAK;AAAA,MACnE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,SAAS;AAAA,QAC1B,MAAM,YAAY,QAAQ;AAAA,QAC1B,WAAW,gCAAgC,WAAW,OAAO,KAAK;AAAA,MACpE;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,SAAS;AAAA,QAC1B,MAAM,YAAY,OAAO;AAAA,QACzB,WAAW,cAAc,WAAW,OAAO,KAAK;AAAA,MAClD;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM,YAAY,SAAS;AAAA,QAC5C,MAAM,YAAY,OAAO;AAAA,QACzB,WAAW,2BAA2B,WAAW,yBAAyB,KAAK;AAAA,MACjF;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,KAAK,YAAY,MAAM,YAAY,SAAS;AAAA,QAC5C,MAAM,YAAY,QAAQ;AAAA,QAC1B,WAAW,cAAc,WAAW,wBAAwB,KAAK;AAAA,MACnE;AAAA,IACF;AACE,aAAO;AAAA,QACL,KAAK,YAAY,MAAM;AAAA,QACvB,MAAM,YAAY;AAAA,QAClB,WAAW,2BAA2B,WAAW,QAAQ,KAAK;AAAA,MAChE;AAAA,EACJ;AACF;AAEA,IAAM,iBAAiB,CAAC,cAAgC;AACtD,QAAM,OAA4B;AAAA,IAChC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,cAAc;AAAA,EAChB;AAEA,QAAM,kBAAiE;AAAA,IACrE,KAAK,EAAE,QAAQ,CAAC,YAAY,MAAM,OAAO,YAAY,CAAC,WAAW;AAAA,IACjE,YAAY,EAAE,QAAQ,CAAC,YAAY,OAAO,kBAAkB;AAAA,IAC5D,aAAa,EAAE,QAAQ,CAAC,YAAY,MAAM,kBAAkB;AAAA,IAE5D,QAAQ,EAAE,KAAK,CAAC,YAAY,MAAM,OAAO,YAAY,CAAC,WAAW;AAAA,IACjE,eAAe,EAAE,KAAK,CAAC,YAAY,OAAO,kBAAkB;AAAA,IAC5D,gBAAgB,EAAE,KAAK,CAAC,YAAY,MAAM,kBAAkB;AAAA,IAE5D,MAAM,EAAE,OAAO,CAAC,YAAY,KAAK,OAAO,WAAW,CAAC,WAAW;AAAA,IAC/D,OAAO,EAAE,MAAM,CAAC,YAAY,KAAK,OAAO,WAAW,CAAC,WAAW;AAAA,EACjE;AAEA,SAAO,EAAE,GAAG,MAAM,GAAG,gBAAgB,SAAS,EAAE;AAClD;AAEO,IAAM,UAAU;AAAA,EAIrB,CACE;AAAA,IACE;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,aAAa;AAAA,IACb,SAAS;AAAA,IACT,YAAY;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IACf;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GACA,QACG;AACH,UAAM,CAAC,WAAW,YAAY,IAAI,SAAS,KAAK;AAChD,UAAM,CAAC,aAAa,cAAc,IAAI,SAAyB,IAAI;AACnE,UAAM,EAAE,OAAO,cAAc,IAAI,iBAAiB;AAAA,MAChD;AAAA,MACA;AAAA,IACF,CAAC;AACD,UAAM,QAAQ;AACd,UAAM,kBAAkB,OAA6C,IAAI;AACzE,UAAM,kBAAkB,OAA6C,IAAI;AACzE,UAAM,SAAS,OAAsB,IAAI;AACzC,UAAM,aAAa,OAAuB,IAAI;AAC9C,UAAM,YAAY,MAAM;AACxB,UAAM,UAAU,WAAW;AAC3B,UAAM,eAAe,gBAAgB;AAErC,UAAM,YACJ,sBAAsB,SAAY,oBAAoB;AAExD,UAAM,gCAAgC,MAAM;AAC1C,UAAI,gBAAgB,SAAS;AAC3B,qBAAa,gBAAgB,OAAO;AACpC,wBAAgB,UAAU;AAAA,MAC5B;AAEA,UAAI,gBAAgB,SAAS;AAC3B,qBAAa,gBAAgB,OAAO;AACpC,wBAAgB,UAAU;AAAA,MAC5B;AAEA,UAAI,OAAO,SAAS;AAClB,6BAAqB,OAAO,OAAO;AACnC,eAAO,UAAU;AAAA,MACnB;AAAA,IACF;AAEA,UAAM,mBAAmB,MAAM;AAC7B,oCAA8B;AAC9B,mBAAa,KAAK;AAAA,IACpB;AAEA,UAAM,iBAAiB;AAAA,MACrB,MACE,cACI,kBAAkB,aAAa,WAAW,QAAQ,SAAS,IAC3D,EAAE,KAAK,GAAG,MAAM,EAAE;AAAA,MACxB,CAAC,aAAa,WAAW,QAAQ,SAAS;AAAA,IAC5C;AACA,UAAM,aAAa,QAAQ,MAAM,qBAAqB,IAAI,GAAG,CAAC,IAAI,CAAC;AACnE,UAAM,gBAAgB,MAAM,MAAM,QAAQ,IAAI,KAAK,MAAM,MAAM,QAAQ,IACpE;AACH,UAAM,cAAc,QAAQ,MAAM,eAAe,SAAS,GAAG,CAAC,SAAS,CAAC;AAIxE,UAAM,gBAAgB;AAAA,MACpB,OAAO;AAAA,QACL;AAAA,QACA,UAAU,WAAW;AAAA,QACrB,YAAY,WAAW;AAAA,QACvB,OAAO,MAAM,OAAO,QAAQ;AAAA,QAC5B,WAAW,MAAM,OAAO,QAAQ,MAAM;AAAA,MACxC;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,MAAM,OAAO,QAAQ;AAAA,QACrB,MAAM,OAAO,QAAQ,MAAM;AAAA,MAC7B;AAAA,IACF;AAGA,cAAU,MAAM;AACd,UAAI,CAAC,aAAa,SAAU;AAE5B,YAAM,iBAAiB,MAAM;AAC3B,YAAI,WAAW,SAAS;AACtB,yBAAe,WAAW,QAAQ,sBAAsB,CAAC;AAAA,QAC3D;AAAA,MACF;AAEA,qBAAe;AAEf,aAAO,iBAAiB,UAAU,gBAAgB,IAAI;AACtD,aAAO,iBAAiB,UAAU,cAAc;AAEhD,aAAO,MAAM;AACX,eAAO,oBAAoB,UAAU,gBAAgB,IAAI;AACzD,eAAO,oBAAoB,UAAU,cAAc;AAAA,MACrD;AAAA,IACF,GAAG,CAAC,SAAS,CAAC;AAEd,UAAM,cAAc,MAAM;AACxB,oCAA8B;AAE9B,UAAI,CAAC,YAAY,OAAO,aAAa,aAAa;AAChD,iBAAS;AAAA,UACP,IAAI,YAAY,oBAAoB,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;AAAA,QAC/D;AAAA,MACF;AAGA,UAAI,WAAW,SAAS;AACtB,uBAAe,WAAW,QAAQ,sBAAsB,CAAC;AAGzD,eAAO,UAAU,sBAAsB,MAAM;AAC3C,iBAAO,UAAU,sBAAsB,MAAM;AAC3C,gBAAI,aAAa,GAAG;AAClB,8BAAgB,UAAU,WAAW,MAAM;AACzC,6BAAa,IAAI;AAAA,cACnB,GAAG,UAAU;AAAA,YACf,OAAO;AACL,2BAAa,IAAI;AAAA,YACnB;AAAA,UACF,CAAC;AAAA,QACH,CAAC;AAAA,MACH;AAAA,IACF;AAEA,UAAM,qBAAqB,CAAC,UAAyC;AAMnE,YAAM,SAAS,MAAM;AAErB,UAAI,UAAU,OAAO,OAAO,YAAY,YAAY;AAClD,YAAI;AACJ,YAAI;AACF,2BAAiB,OAAO,QAAQ,gBAAgB;AAAA,QAClD,QAAQ;AAGN,2BAAiB;AAAA,QACnB;AAEA,YAAI,CAAC,eAAgB;AAAA,MACvB;AAEA,kBAAY;AAAA,IACd;AAEA,UAAM,cAAc,MAAM;AACxB,oCAA8B;AAE9B,UAAI,aAAa,GAAG;AAClB,wBAAgB,UAAU,WAAW,MAAM;AACzC,uBAAa,KAAK;AAAA,QACpB,GAAG,UAAU;AAAA,MACf,OAAO;AACL,qBAAa,KAAK;AAAA,MACpB;AAAA,IACF;AAEA,cAAU,MAAM;AACd,UAAI,SAAU;AAEd,YAAM,eAAe,CAAC,UAAyB;AAC7C,YAAI,MAAM,QAAQ,YAAY,WAAW;AACvC,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,YAAM,yBAAyB,MAAM;AACnC,YAAI,SAAS,oBAAoB,UAAU;AACzC,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,YAAM,oBAAoB,CAAC,UAAiB;AAC1C,cAAM,EAAE,WAAW,gBAAgB,IAChC,MAAsB,UAAU,CAAC;AAEpC,YAAI,oBAAoB,WAAW;AACjC,2BAAiB;AAAA,QACnB;AAAA,MACF;AAEA,eAAS,iBAAiB,WAAW,YAAY;AACjD,eAAS,iBAAiB,oBAAoB,sBAAsB;AACpE,eAAS,iBAAiB,oBAAoB,iBAAiB;AAE/D,aAAO,MAAM;AACX,iBAAS,oBAAoB,WAAW,YAAY;AACpD,iBAAS;AAAA,UACP;AAAA,UACA;AAAA,QACF;AACA,iBAAS,oBAAoB,oBAAoB,iBAAiB;AAClE,sCAA8B;AAAA,MAChC;AAAA,IACF,GAAG,CAAC,WAAW,SAAS,CAAC;AAEzB,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,KAAK;AAAA,QACL,UAAS;AAAA,QACT,SAAQ;AAAA,QACR,cAAc;AAAA,QACd,cAAc;AAAA,QACd,SAAS;AAAA,QACT,QAAQ;AAAA,QACR;AAAA,QACA,OAAO,EAAE,QAAQ,cAAc;AAAA,QAC/B,oBAAkB,YAAY,YAAY;AAAA,QAEzC;AAAA;AAAA,UACA,CAAC,YAAY,eACZ,gBAAAA,KAAC,UACC;AAAA,YAAC;AAAA;AAAA,cACC;AAAA,cACA,eAAa;AAAA,cACb,iBAAe;AAAA,cACf,UAAS;AAAA,cACT,iBAAiB,MAAM,OAAO,MAAM;AAAA,cACpC;AAAA,cACA,iBAAiB;AAAA,cACjB,mBAAmB;AAAA,cACnB,QAAQ,eAAe,aAAa;AAAA,cACpC,IAAI;AAAA,cACJ,MAAK;AAAA,cACL,eAAa,CAAC;AAAA,cACd,cAAc;AAAA,cACd,cAAc;AAAA,cACd,OAAO;AAAA,gBACL,GAAG;AAAA;AAAA,gBAEH,QACE;AAAA,gBACF,cACE;AAAA,gBACF,SAAS,YAAY,IAAI;AAAA,gBACzB,YAAY,YAAY,YAAY;AAAA,gBACpC,YACE;AAAA,gBACF,eAAe,YAAY,SAAS;AAAA,gBACpC,YAAY;AAAA,gBACZ,OAAO;AAAA,gBACP,UAAU,YAAY;AAAA,gBACtB,UAAU;AAAA,gBACV,YAAY,YAAY,uBAAuB;AAAA;AAAA,gBAC/C,GAAG;AAAA,cACL;AAAA,cAEA;AAAA,gCAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,UAAS;AAAA,oBACT,iBAAiB,MAAM,OAAO,MAAM;AAAA,oBACpC,OAAO;AAAA,sBACL,GAAG;AAAA,sBACH,oBAAoB;AAAA,sBACpB,0BAA0B;AAAA,oBAC5B;AAAA;AAAA,gBACF;AAAA,gBACA,gBAAAA,KAAC,sBAAsB,UAAtB,EAA+B,OAAO,eACrC,0BAAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,OAAO;AAAA,sBACL,UAAU;AAAA,sBACV,cAAc;AAAA,sBACd,UAAU;AAAA,sBACV,YAAY;AAAA;AAAA;AAAA;AAAA,sBAIZ,UAAU,WAAW;AAAA,sBACrB,YAAY,WAAW;AAAA,sBACvB,YAAY;AAAA,sBACZ,OAAO,MAAM,OAAO,QAAQ;AAAA,oBAC9B;AAAA,oBAEC,iBAAO,YAAY,YAAY,OAAO,YAAY,WACjD,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,OAAO,MAAM,OAAO,QAAQ;AAAA,wBAC5B,UAAU,WAAW;AAAA,wBACrB,YAAY,OAAO,wBAAwB;AAAA,wBAC3C,OAAO;AAAA,0BACL,YAAY,WAAW;AAAA,0BACvB,YAAY;AAAA,wBACd;AAAA,wBAEC;AAAA;AAAA,oBACH,IAEA;AAAA;AAAA,gBAEJ,GACF;AAAA;AAAA;AAAA,UACF,GACF;AAAA;AAAA;AAAA,IAEJ;AAAA,EAEJ;AACF;AAEA,QAAQ,cAAc;;;AMjdtB,SAAS,oBAAAC,yBAAiD;AA4CtD,gBAAAC,YAAA;AA1BG,IAAM,cAA+D,CAAC;AAAA,EAC3E;AAAA,EACA,SAAS;AAAA,EACT;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AACF,MAAM;AACJ,QAAM,YAAY,wBAAwB;AAC1C,QAAM,EAAE,MAAM,IAAIC,kBAAiB,EAAE,WAAW,oBAAoB,CAAC;AAErE,QAAM,eAAe,QAAQ,WAAW,QAAQ;AAChD,QAAM,OAAO,qBAAqB,YAAY;AAC9C,QAAM,gBACJ,SAAS,WAAW,SAAS,MAAM,OAAO,QAAQ;AACpD,QAAM,aAAa,SACf;AAAA,IACG,MAA4C;AAAA,IAC7C;AAAA,EACF,IACA;AAEJ,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,eAAa;AAAA,MACb,OAAO;AAAA,MACP,UAAU,KAAK;AAAA,MACf,YAAY,OAAO,UAAU;AAAA,MAC7B,OAAO;AAAA,QACL,YAAY,KAAK;AAAA,QACjB,YAAY;AAAA,QACZ,GAAG;AAAA,MACL;AAAA,MAEC;AAAA;AAAA,EACH;AAEJ;AAEA,YAAY,cAAc;;;AC7D1B,SAAS,oBAAAE,yBAAiD;AA0FpD,gBAAAC,YAAA;AAtEC,IAAM,cAA+D,CAAC;AAAA,EAC3E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AAAA,EACT,YAAY;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAe;AAAA,EACf;AAAA,EACA;AACF,MAAM;AACJ,QAAM,YAAY,wBAAwB;AAC1C,QAAM,EAAE,MAAM,IAAIC,kBAAiB,EAAE,WAAW,oBAAoB,CAAC;AAErE,QAAM,eAAe,QAAQ,WAAW,QAAQ;AAChD,QAAM,OAAO,qBAAqB,YAAY;AAC9C,QAAM,gBACJ,SAAS,WAAW,aAAa,MAAM,OAAO,QAAQ,MAAM;AAC9D,QAAM,aAAa,SACf;AAAA,IACG,MAA4C;AAAA,IAC7C;AAAA,EACF,IACA;AAGJ,QAAM,cACJ,WAAW,WACP,MAAM;AAAA,IACJ,oBAAI,IAAI;AAAA,MACN,GAAI,MAAM,IAAI,MAAM,KAAK,EAAE,OAAO,OAAO,IAAI,CAAC;AAAA,MAC9C;AAAA,MACA;AAAA,IACF,CAAC;AAAA,EACH,EAAE,KAAK,GAAG,IACV;AAEN,QAAM,cAAc,CAAC,UAAgB;AACnC,QAAI,CAAC,QAAS;AACd,WAAO,iBAAiB;AACxB,YAAQ;AAAA,EACV;AAEA,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,IAAG;AAAA,MACH;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL,SAAS;AAAA,MACT,SAAS;AAAA,MACT,MAAK;AAAA,MACL,QAAO;AAAA,MACP,SAAQ;AAAA,MACR,YAAW;AAAA,MACX;AAAA,MACA,eAAa;AAAA,MACb,YAAY,EAAE,SAAS,IAAI;AAAA,MAC3B,YAAY;AAAA,QACV,cAAc,MAAM,OAAO,OAAO;AAAA,QAClC,cAAc;AAAA,QACd,cAAc;AAAA,QACd,eAAe;AAAA,MACjB;AAAA,MAEA,0BAAAA;AAAA,QAAC;AAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU,KAAK;AAAA,UACf,YAAY,OAAO,UAAU;AAAA,UAC7B,gBAAgB,YAAY,cAAc;AAAA,UAC1C,OAAO,EAAE,YAAY,KAAK,YAAY,GAAG,MAAM;AAAA,UAE9C;AAAA;AAAA,MACH;AAAA;AAAA,EACF;AAEJ;AAEA,YAAY,cAAc;","names":["jsx","jsx","jsx","useResolvedTheme","jsx","useResolvedTheme","useResolvedTheme","jsx","useResolvedTheme"]}
|
|
1
|
+
{"version":3,"sources":["../../src/Tooltip.tsx","../../../../foundation/primitives-native/src/Box.tsx","../../../../foundation/primitives-native/src/Text.tsx","../../src/Portal.native.tsx","../../src/TooltipContentContext.tsx","../../src/contentTypography.ts","../../src/TooltipText.tsx","../../src/TooltipLink.tsx"],"sourcesContent":["import React, { forwardRef, useState, useMemo, useEffect, useRef } from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport {\n useResolvedTheme,\n useId,\n isNative,\n useModalId,\n useOverlayLayer,\n LAYER_OFFSET,\n type ThemeOverrideProps,\n} from \"@xsolla/xui-core\";\nimport type {\n TooltipContentStyles,\n TooltipPlacement,\n TooltipProps,\n TooltipSize,\n} from \"./types\";\nimport { Portal } from \"./Portal\";\nimport { TooltipContentContext } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipTypographyTokens,\n} from \"./contentTypography\";\n\nconst TOOLTIP_OPEN_EVENT = \"xui-tooltip-open\";\ntype TooltipTheme = {\n colors: {\n layer: {\n float: string;\n };\n content: {\n primary: string;\n brand: {\n primary: string;\n };\n };\n };\n shape: {\n tooltip: Record<TooltipSize, { borderRadius: number | string }>;\n };\n typographyTokens?: TooltipTypographyTokens;\n};\n\nconst ARROW_SIZE = 10;\nconst ARROW_HALF = ARROW_SIZE / 2;\n// Keeps the arrow clear of the panel's corner radius (8px for `md`).\nconst ARROW_EDGE_OFFSET = 12;\nconst ARROW_CENTER_INSET = ARROW_EDGE_OFFSET + ARROW_HALF;\n\n// Re-centres the arrow on triggers too narrow for the flush inset (FEP-889).\nconst getArrowAlignmentShift = (triggerWidth: number) =>\n Math.max(0, ARROW_CENTER_INSET - triggerWidth / 2);\n\nconst getPositionStyles = (\n triggerRect: DOMRect,\n placement: TooltipPlacement,\n offset: number,\n isVisible: boolean\n) => {\n const slideDistance = 8;\n const scale = isVisible ? \"scale(1)\" : \"scale(0.95)\";\n const slideOffset = isVisible ? 0 : -slideDistance;\n const arrowShift = getArrowAlignmentShift(triggerRect.width);\n\n switch (placement) {\n case \"top\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-left\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"top-right\":\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n case \"bottom\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left + triggerRect.width / 2,\n transform: `translateX(-50%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-left\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.right + arrowShift,\n transform: `translateX(-100%) translateY(${slideOffset}px) ${scale}`,\n };\n case \"bottom-right\":\n return {\n top: triggerRect.bottom + offset,\n left: triggerRect.left - arrowShift,\n transform: `translateY(${slideOffset}px) ${scale}`,\n };\n case \"left\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.left - offset,\n transform: `translateX(calc(-100% - ${slideOffset}px)) translateY(-50%) ${scale}`,\n };\n case \"right\":\n return {\n top: triggerRect.top + triggerRect.height / 2,\n left: triggerRect.right + offset,\n transform: `translateX(${slideOffset}px) translateY(-50%) ${scale}`,\n };\n default:\n return {\n top: triggerRect.top - offset,\n left: triggerRect.left,\n transform: `translateY(calc(-100% - ${slideOffset}px)) ${scale}`,\n };\n }\n};\n\nconst getArrowStyles = (placement: TooltipPlacement) => {\n const base: React.CSSProperties = {\n width: ARROW_SIZE,\n height: ARROW_SIZE,\n transform: \"rotate(45deg)\",\n borderRadius: 1,\n };\n\n const placementStyles: Record<TooltipPlacement, React.CSSProperties> = {\n top: { bottom: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"top-left\": { bottom: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"top-right\": { bottom: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n bottom: { top: -ARROW_HALF, left: \"50%\", marginLeft: -ARROW_HALF },\n \"bottom-left\": { top: -ARROW_HALF, right: ARROW_EDGE_OFFSET },\n \"bottom-right\": { top: -ARROW_HALF, left: ARROW_EDGE_OFFSET },\n\n left: { right: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n right: { left: -ARROW_HALF, top: \"50%\", marginTop: -ARROW_HALF },\n };\n\n return { ...base, ...placementStyles[placement] };\n};\n\nexport const Tooltip = forwardRef<\n HTMLDivElement,\n TooltipProps & ThemeOverrideProps\n>(\n (\n {\n content,\n children,\n size = \"md\",\n delayEnter = 0,\n delayLeave = 100,\n offset = 12,\n placement = \"top\",\n maxWidth,\n controlledVisible,\n style,\n \"data-testid\": dataTestId,\n className,\n testID,\n themeMode,\n themeProductContext,\n },\n ref\n ) => {\n const [isHovered, setIsHovered] = useState(false);\n const [triggerRect, setTriggerRect] = useState<DOMRect | null>(null);\n const { theme: resolvedTheme } = useResolvedTheme({\n themeMode,\n themeProductContext,\n });\n const theme = resolvedTheme as TooltipTheme;\n const enterTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const leaveTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const rafRef = useRef<number | null>(null);\n const triggerRef = useRef<HTMLDivElement>(null);\n const tooltipId = useId();\n const modalId = useModalId();\n const overlayLayer = useOverlayLayer();\n\n const isVisible =\n controlledVisible !== undefined ? controlledVisible : isHovered;\n\n const clearPendingVisibilityUpdates = () => {\n if (enterTimeoutRef.current) {\n clearTimeout(enterTimeoutRef.current);\n enterTimeoutRef.current = null;\n }\n\n if (leaveTimeoutRef.current) {\n clearTimeout(leaveTimeoutRef.current);\n leaveTimeoutRef.current = null;\n }\n\n if (rafRef.current) {\n cancelAnimationFrame(rafRef.current);\n rafRef.current = null;\n }\n };\n\n const forceHideTooltip = () => {\n clearPendingVisibilityUpdates();\n setIsHovered(false);\n };\n\n const positionStyles = useMemo(\n () =>\n triggerRect\n ? getPositionStyles(triggerRect, placement, offset, isVisible)\n : { top: 0, left: 0 },\n [triggerRect, placement, offset, isVisible]\n );\n const typoStyles = useMemo(() => getTooltipTypoStyles(size), [size]);\n const borderRadius = (theme.shape.tooltip[size] ?? theme.shape.tooltip.md)\n .borderRadius;\n const arrowStyles = useMemo(() => getArrowStyles(placement), [placement]);\n\n // Published to arbitrary `content` so nested helpers (TooltipText,\n // TooltipLink) inherit this tooltip's size scale and colour tokens.\n const contentStyles = useMemo<TooltipContentStyles>(\n () => ({\n size,\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n color: theme.colors.content.primary,\n linkColor: theme.colors.content.brand.primary,\n }),\n [\n size,\n typoStyles,\n theme.colors.content.primary,\n theme.colors.content.brand.primary,\n ]\n );\n\n // Update trigger position when tooltip becomes visible and on scroll/resize\n useEffect(() => {\n if (!isVisible || isNative) return;\n\n const updatePosition = () => {\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n }\n };\n\n updatePosition();\n\n window.addEventListener(\"scroll\", updatePosition, true);\n window.addEventListener(\"resize\", updatePosition);\n\n return () => {\n window.removeEventListener(\"scroll\", updatePosition, true);\n window.removeEventListener(\"resize\", updatePosition);\n };\n }, [isVisible]);\n\n const showTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (!isNative && typeof document !== \"undefined\") {\n document.dispatchEvent(\n new CustomEvent(TOOLTIP_OPEN_EVENT, { detail: { tooltipId } })\n );\n }\n\n // Update position before showing to prevent pop-in\n if (triggerRef.current) {\n setTriggerRect(triggerRef.current.getBoundingClientRect());\n\n // Double RAF to ensure position is rendered before showing tooltip\n rafRef.current = requestAnimationFrame(() => {\n rafRef.current = requestAnimationFrame(() => {\n if (delayEnter > 0) {\n enterTimeoutRef.current = setTimeout(() => {\n setIsHovered(true);\n }, delayEnter);\n } else {\n setIsHovered(true);\n }\n });\n });\n }\n };\n\n const showTooltipOnFocus = (event: React.FocusEvent<HTMLElement>) => {\n // Only reveal the tooltip on intentional keyboard focus. Focus that the\n // browser restores to the trigger when the tab/window regains focus — as\n // well as focus from a mouse click — must not re-trigger the tooltip\n // (FEP-832). `:focus-visible` encodes exactly this heuristic: it matches\n // for keyboard navigation but not for pointer-driven or restored focus.\n const target = event.target as HTMLElement | null;\n\n if (target && typeof target.matches === \"function\") {\n let isFocusVisible: boolean;\n try {\n isFocusVisible = target.matches(\":focus-visible\");\n } catch {\n // Legacy browsers without :focus-visible support — preserve the\n // previous behaviour of showing on any focus.\n isFocusVisible = true;\n }\n\n if (!isFocusVisible) return;\n }\n\n showTooltip();\n };\n\n const hideTooltip = () => {\n clearPendingVisibilityUpdates();\n\n if (delayLeave > 0) {\n leaveTimeoutRef.current = setTimeout(() => {\n setIsHovered(false);\n }, delayLeave);\n } else {\n setIsHovered(false);\n }\n };\n\n useEffect(() => {\n if (isNative) return;\n\n const handleEscape = (event: KeyboardEvent) => {\n if (event.key === \"Escape\" && isVisible) {\n forceHideTooltip();\n }\n };\n\n const handleVisibilityChange = () => {\n if (document.visibilityState === \"hidden\") {\n forceHideTooltip();\n }\n };\n\n const handleTooltipOpen = (event: Event) => {\n const { tooltipId: activeTooltipId } =\n (event as CustomEvent).detail ?? {};\n\n if (activeTooltipId !== tooltipId) {\n forceHideTooltip();\n }\n };\n\n document.addEventListener(\"keydown\", handleEscape);\n document.addEventListener(\"visibilitychange\", handleVisibilityChange);\n document.addEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n\n return () => {\n document.removeEventListener(\"keydown\", handleEscape);\n document.removeEventListener(\n \"visibilitychange\",\n handleVisibilityChange\n );\n document.removeEventListener(TOOLTIP_OPEN_EVENT, handleTooltipOpen);\n clearPendingVisibilityUpdates();\n };\n }, [isVisible, tooltipId]);\n\n return (\n <Box\n testID={testID}\n ref={triggerRef}\n position=\"relative\"\n display=\"inline-flex\"\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n onFocus={showTooltipOnFocus}\n onBlur={hideTooltip}\n className={className}\n style={{ height: \"fit-content\" }}\n aria-describedby={isVisible ? tooltipId : undefined}\n >\n {children}\n {!isNative && triggerRect && (\n <Portal>\n <Box\n ref={ref}\n data-testid={dataTestId}\n data-modal-id={modalId}\n position=\"fixed\"\n backgroundColor={theme.colors.layer.float}\n borderRadius={borderRadius}\n paddingVertical={8}\n paddingHorizontal={12}\n zIndex={overlayLayer + LAYER_OFFSET.tooltip}\n id={tooltipId}\n role=\"tooltip\"\n aria-hidden={!isVisible}\n onMouseEnter={showTooltip}\n onMouseLeave={hideTooltip}\n style={{\n ...positionStyles,\n // https://stackoverflow.com/questions/62844007/how-to-apply-tool-tip-arrow-triangle-shadow\n filter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n WebkitFilter:\n \"drop-shadow(0 6px 10px rgba(7, 7, 8, 0.1)) drop-shadow(0 2px 3px rgba(7, 7, 8, 0.2))\",\n opacity: isVisible ? 1 : 0,\n visibility: isVisible ? \"visible\" : \"hidden\",\n transition:\n \"opacity 150ms cubic-bezier(.4,0,.2,1), transform 150ms cubic-bezier(.4,0,.2,1), visibility 150ms cubic-bezier(.4,0,.2,1)\",\n pointerEvents: isVisible ? \"auto\" : \"none\",\n whiteSpace: \"normal\",\n width: \"max-content\",\n maxWidth: maxWidth ?? \"none\",\n overflow: \"visible\",\n willChange: isVisible ? \"transform, opacity\" : \"auto\", // optimize rendering and ensure more stable positioning\n ...style,\n }}\n >\n <Box\n position=\"absolute\"\n backgroundColor={theme.colors.layer.float}\n style={{\n ...arrowStyles,\n backfaceVisibility: \"hidden\",\n WebkitBackfaceVisibility: \"hidden\",\n }}\n />\n <TooltipContentContext.Provider value={contentStyles}>\n <Box\n style={{\n wordWrap: \"break-word\",\n overflowWrap: \"break-word\",\n maxWidth: \"100%\",\n whiteSpace: \"normal\",\n // Custom `content` inherits the tooltip's own type scale,\n // so plain markup (`<strong>`, `<a>`, bare strings) reads\n // at the right size without re-deriving it per call site.\n fontSize: typoStyles.fontSize,\n lineHeight: typoStyles.lineHeight,\n fontWeight: DEFAULT_BODY_FONT_WEIGHT,\n color: theme.colors.content.primary,\n }}\n >\n {typeof content === \"string\" || typeof content === \"number\" ? (\n <Text\n color={theme.colors.content.primary}\n fontSize={typoStyles.fontSize}\n fontWeight={String(DEFAULT_BODY_FONT_WEIGHT)}\n style={{\n lineHeight: typoStyles.lineHeight,\n whiteSpace: \"pre-line\",\n }}\n >\n {content}\n </Text>\n ) : (\n content\n )}\n </Box>\n </TooltipContentContext.Provider>\n </Box>\n </Portal>\n )}\n </Box>\n );\n }\n);\n\nTooltip.displayName = \"Tooltip\";\n","import React from \"react\";\nimport {\n View,\n Pressable,\n Image,\n ViewStyle,\n ImageStyle,\n DimensionValue,\n AnimatableNumericValue,\n AccessibilityRole,\n} from \"react-native\";\nimport { BoxProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleToAccessibilityRole: Record<string, AccessibilityRole> = {\n button: \"button\",\n link: \"link\",\n img: \"image\",\n image: \"image\",\n summary: \"summary\",\n switch: \"switch\",\n checkbox: \"checkbox\",\n radio: \"radio\",\n heading: \"header\",\n text: \"text\",\n search: \"search\",\n alert: \"alert\",\n none: \"none\",\n presentation: \"none\",\n progressbar: \"progressbar\",\n scrollbar: \"scrollbar\",\n adjustable: \"adjustable\",\n tab: \"tab\",\n menu: \"menu\",\n menuitem: \"menuitem\",\n list: \"list\",\n timer: \"timer\",\n};\n\n/** RN ViewStyle.gap is typed as number (Yoga gap), not DimensionValue. */\nconst toGapValue = (gap: number | string | undefined): number | undefined => {\n if (gap === undefined) return undefined;\n if (typeof gap === \"number\") return gap;\n const pxMatch = /^(\\d+(?:\\.\\d+)?)px$/.exec(gap);\n if (pxMatch) return Number(pxMatch[1]);\n const asNumber = Number(gap);\n return Number.isFinite(asNumber) ? asNumber : undefined;\n};\n\n/**\n * Yoga has no inline formatting context, so RN's ViewStyle.display only\n * accepts \"flex\" | \"none\". Every inline-ish web value collapses to a plain\n * flex container — the box already fills only its content on native, which is\n * what those callers wanted on web anyway. Returning undefined (rather than\n * \"flex\") leaves RN's own default in place.\n */\nconst toNativeDisplay = (\n display: BoxProps[\"display\"]\n): ViewStyle[\"display\"] => (display === \"none\" ? \"none\" : undefined);\n\nexport const Box: React.FC<BoxProps> = ({\n children,\n onPress,\n onLayout,\n onMoveShouldSetResponder,\n onResponderGrant,\n onResponderMove,\n onResponderRelease,\n onResponderTerminate,\n backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius,\n borderStyle,\n height,\n padding,\n paddingHorizontal,\n paddingVertical,\n margin,\n marginTop,\n marginBottom,\n marginLeft,\n marginRight,\n display,\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position,\n top,\n bottom,\n left,\n right,\n width,\n minWidth,\n minHeight,\n maxWidth,\n maxHeight,\n flex,\n flexShrink,\n gap,\n overflow,\n opacity,\n zIndex,\n hoverStyle,\n pressStyle,\n style,\n disabled,\n \"data-testid\": dataTestId,\n testID,\n as,\n src,\n alt,\n ...rest\n}) => {\n const getContainerStyle = (pressed?: boolean): ViewStyle => ({\n backgroundColor:\n pressed && pressStyle?.backgroundColor\n ? pressStyle.backgroundColor\n : backgroundColor,\n borderColor,\n borderWidth,\n borderBottomWidth,\n borderBottomColor,\n borderTopWidth,\n borderTopColor,\n borderLeftWidth,\n borderLeftColor,\n borderRightWidth,\n borderRightColor,\n borderRadius: borderRadius as AnimatableNumericValue,\n borderStyle: borderStyle as ViewStyle[\"borderStyle\"],\n overflow,\n opacity: opacity ?? (disabled ? 0.5 : undefined),\n zIndex,\n height: height as DimensionValue,\n width: width as DimensionValue,\n minWidth: minWidth as DimensionValue,\n minHeight: minHeight as DimensionValue,\n maxWidth: maxWidth as DimensionValue,\n maxHeight: maxHeight as DimensionValue,\n padding: padding as DimensionValue,\n paddingHorizontal: paddingHorizontal as DimensionValue,\n paddingVertical: paddingVertical as DimensionValue,\n margin: margin as DimensionValue,\n marginTop: marginTop as DimensionValue,\n marginBottom: marginBottom as DimensionValue,\n marginLeft: marginLeft as DimensionValue,\n marginRight: marginRight as DimensionValue,\n display: toNativeDisplay(display),\n flexDirection,\n flexWrap,\n alignItems,\n justifyContent,\n alignSelf,\n position: position as ViewStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n flex,\n flexShrink,\n gap: toGapValue(gap),\n ...(style as ViewStyle),\n });\n\n const finalTestID = dataTestId || testID;\n\n // Map web a11y props; drop the rest of the web-only attributes before\n // spreading onto RN hosts (unknown props warn at runtime).\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const {\n role,\n tabIndex,\n onKeyDown,\n onKeyUp,\n \"aria-label\": ariaLabel,\n \"aria-labelledby\": _ariaLabelledBy,\n \"aria-current\": _ariaCurrent,\n \"aria-disabled\": ariaDisabled,\n \"aria-live\": ariaLive,\n \"aria-busy\": ariaBusy,\n className,\n \"data-testid\": _dataTestId,\n cursor: _cursor,\n type: _type,\n ...nativeRest\n } = rest as Record<string, unknown>;\n\n const accessibilityRole =\n (typeof role === \"string\" && roleToAccessibilityRole[role]) ||\n (as === \"button\" ? \"button\" : undefined);\n const isDisabled = Boolean(disabled || ariaDisabled);\n const accessibilityState = {\n disabled: isDisabled || undefined,\n busy: Boolean(ariaBusy) || undefined,\n };\n const accessibilityLiveRegion =\n ariaLive === \"polite\" || ariaLive === \"assertive\" ? ariaLive : undefined;\n\n // Handle as=\"img\" for React Native\n if (as === \"img\" && src) {\n const imageStyle: ImageStyle = {\n width: width as DimensionValue,\n height: height as DimensionValue,\n borderRadius: borderRadius as number,\n position: position as ImageStyle[\"position\"],\n top: top as DimensionValue,\n bottom: bottom as DimensionValue,\n left: left as DimensionValue,\n right: right as DimensionValue,\n ...(style as ImageStyle),\n };\n\n return (\n <Image\n source={{ uri: src }}\n style={imageStyle}\n testID={finalTestID}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : alt}\n resizeMode=\"cover\"\n {...nativeRest}\n />\n );\n }\n\n // Prefer Pressable whenever the node is interactive or explicitly a button,\n // so disabled / aria-disabled controls stay in the a11y tree as buttons.\n if (onPress || as === \"button\") {\n return (\n <Pressable\n onPress={!isDisabled && onPress ? onPress : undefined}\n disabled={isDisabled}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n style={({ pressed }) => getContainerStyle(pressed)}\n testID={finalTestID}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={\n typeof ariaLabel === \"string\" ? ariaLabel : undefined\n }\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </Pressable>\n );\n }\n\n return (\n <View\n style={getContainerStyle()}\n testID={finalTestID}\n onLayout={onLayout}\n onMoveShouldSetResponder={onMoveShouldSetResponder}\n onResponderGrant={onResponderGrant}\n onResponderMove={onResponderMove}\n onResponderRelease={onResponderRelease}\n onResponderTerminate={onResponderTerminate}\n accessibilityRole={accessibilityRole}\n accessibilityLabel={typeof ariaLabel === \"string\" ? ariaLabel : undefined}\n accessibilityState={accessibilityState}\n accessibilityLiveRegion={accessibilityLiveRegion}\n {...nativeRest}\n >\n {children}\n </View>\n );\n};\n","import React from \"react\";\nimport {\n Text as RNText,\n TextStyle,\n AccessibilityRole,\n StyleSheet,\n} from \"react-native\";\nimport { TextProps } from \"@xsolla/xui-primitives-core\";\n\nconst roleMap: Record<string, AccessibilityRole> = {\n alert: \"alert\",\n heading: \"header\",\n button: \"button\",\n link: \"link\",\n text: \"text\",\n};\n\nconst parseNumericValue = (\n value: string | number | undefined\n): number | undefined => {\n if (value === undefined) return undefined;\n if (typeof value === \"number\") return value;\n const parsed = parseFloat(value);\n return isNaN(parsed) ? undefined : parsed;\n};\n\nexport const Text: React.FC<TextProps> = ({\n children,\n color,\n fontSize,\n fontWeight,\n fontFamily,\n textAlign,\n lineHeight,\n numberOfLines,\n id,\n role,\n testID,\n \"data-testid\": dataTestId,\n style: styleProp,\n ...props\n}) => {\n let resolvedFontFamily = fontFamily\n ? fontFamily.split(\",\")[0].replace(/['\"]/g, \"\").trim()\n : undefined;\n\n if (\n resolvedFontFamily === \"Pilat Wide\" ||\n resolvedFontFamily === \"Pilat Wide Bold\" ||\n resolvedFontFamily === \"Aktiv Grotesk\"\n ) {\n resolvedFontFamily = undefined;\n }\n\n const incomingStyle = StyleSheet.flatten(styleProp) as TextStyle | undefined;\n\n const baseStyle: TextStyle = {\n color: color ?? incomingStyle?.color,\n fontSize: typeof fontSize === \"number\" ? fontSize : undefined,\n fontWeight: fontWeight as TextStyle[\"fontWeight\"],\n fontFamily: resolvedFontFamily,\n textDecorationLine: props.textDecoration as TextStyle[\"textDecorationLine\"],\n textAlign: textAlign ?? incomingStyle?.textAlign,\n lineHeight: parseNumericValue(lineHeight ?? incomingStyle?.lineHeight),\n marginTop: parseNumericValue(\n incomingStyle?.marginTop as number | string | undefined\n ),\n marginBottom: parseNumericValue(\n incomingStyle?.marginBottom as number | string | undefined\n ),\n };\n\n const accessibilityRole = role ? roleMap[role] : undefined;\n\n return (\n <RNText\n style={baseStyle}\n numberOfLines={numberOfLines}\n testID={dataTestId || testID || id}\n accessibilityRole={accessibilityRole}\n >\n {children}\n </RNText>\n );\n};\n","import { ReactNode } from \"react\";\n\ninterface PortalProps {\n children: ReactNode;\n}\n\n// Portal not supported on React Native - tooltip content renders inline\nexport const Portal = ({ children }: PortalProps) => {\n return <>{children}</>;\n};\n","import { createContext, useContext } from \"react\";\nimport type { TooltipContentStyles } from \"./types\";\n\n/**\n * Publishes the surrounding tooltip's resolved typography and colour tokens to\n * whatever is rendered inside its `content`, so `TooltipText` / `TooltipLink`\n * inherit the tooltip's size without the caller repeating it.\n *\n * `null` when the consumer is rendered outside a `Tooltip` — the helpers then\n * fall back to their own defaults.\n */\nexport const TooltipContentContext = createContext<TooltipContentStyles | null>(\n null\n);\n\nexport const useTooltipContentStyles = (): TooltipContentStyles | null =>\n useContext(TooltipContentContext);\n","import type { TooltipSize } from \"./types\";\n\n/**\n * Per-size font metrics for tooltip copy. Mirrors the tooltip size matrix in\n * the Figma UI kit (node 5680-32928).\n */\nexport const getTooltipTypoStyles = (size: TooltipSize) => {\n switch (size) {\n case \"sm\":\n return { fontSize: 14, lineHeight: \"16px\" };\n case \"md\":\n return { fontSize: 16, lineHeight: \"18px\" };\n case \"lg\":\n return { fontSize: 18, lineHeight: \"20px\" };\n case \"xl\":\n return { fontSize: 20, lineHeight: \"22px\" };\n default:\n return { fontSize: 16, lineHeight: \"18px\" };\n }\n};\n\n/**\n * Body typography token whose scale matches each tooltip size. Used to resolve\n * the *accent* (bold) font weight for emphasised copy inside a tooltip.\n *\n * `xl` has no body token of its own — the body scale tops out at 18px\n * (`body-lg`) — so it reuses `body-lg`'s accent weight rather than hardcoding\n * a weight the active product context may not use.\n */\nconst TOOLTIP_BODY_VARIANT: Record<TooltipSize, string> = {\n sm: \"body-sm\",\n md: \"body-md\",\n lg: \"body-lg\",\n xl: \"body-lg\",\n};\n\n/** Fallbacks for a resolved theme that predates `typographyTokens`. */\nexport const DEFAULT_BODY_FONT_WEIGHT = 400;\nexport const DEFAULT_ACCENT_FONT_WEIGHT = 500;\n\nexport interface TooltipTypographyTokens {\n basic?: Record<\n string,\n { fontWeight?: number; accent?: { fontWeight?: number } } | undefined\n >;\n}\n\n/** The slice of the resolved theme this module reads. */\nexport interface TooltipThemeTypography {\n typographyTokens?: TooltipTypographyTokens;\n}\n\n/**\n * Resolves the accent font weight for `size` from the theme's body typography\n * scale, so bold tooltip copy follows the active product context (b2b/b2c use\n * 500, corpsite uses 600) instead of a hardcoded weight.\n */\nexport const getTooltipAccentFontWeight = (\n typographyTokens: TooltipTypographyTokens | undefined,\n size: TooltipSize\n): number => {\n const variant = TOOLTIP_BODY_VARIANT[size] ?? TOOLTIP_BODY_VARIANT.md;\n\n return (\n typographyTokens?.basic?.[variant]?.accent?.fontWeight ??\n DEFAULT_ACCENT_FONT_WEIGHT\n );\n};\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipTextProps } from \"./types\";\n\n/**\n * Text inside a `Tooltip`'s `content`, styled with the tooltip's own size\n * scale and `content/primary` colour.\n *\n * Pass `accent` for bold copy — the weight is read from the body accent token\n * matching the tooltip's size, so it tracks the active product context instead\n * of a hardcoded `700`.\n */\nexport const TooltipText: React.FC<TooltipTextProps & ThemeOverrideProps> = ({\n children,\n accent = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.color ?? theme.colors.content.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n return (\n <Text\n testID={testID}\n data-testid={dataTestId}\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n style={{\n lineHeight: typo.lineHeight,\n whiteSpace: \"pre-line\",\n ...style,\n }}\n >\n {children}\n </Text>\n );\n};\n\nTooltipText.displayName = \"TooltipText\";\n","import React from \"react\";\n// @ts-expect-error - this will be resolved at build time\nimport { Box, Text } from \"@xsolla/xui-primitives\";\nimport { useResolvedTheme, type ThemeOverrideProps } from \"@xsolla/xui-core\";\nimport { useTooltipContentStyles } from \"./TooltipContentContext\";\nimport {\n getTooltipTypoStyles,\n getTooltipAccentFontWeight,\n DEFAULT_BODY_FONT_WEIGHT,\n type TooltipThemeTypography,\n} from \"./contentTypography\";\nimport type { TooltipLinkProps } from \"./types\";\n\n/**\n * A link inside a `Tooltip`'s `content`. Uses the `content/brand-primary`\n * token and the tooltip's own size scale, so it sits inline with surrounding\n * `TooltipText` without the caller re-deriving typography.\n *\n * The tooltip surface is hoverable, so the link is reachable with a pointer.\n * It is **not** reachable by keyboard — tabbing away from the trigger blurs it\n * and dismisses the tooltip. When a link must be keyboard-operable, use\n * [Toggletip](../../toggletip) instead.\n */\nexport const TooltipLink: React.FC<TooltipLinkProps & ThemeOverrideProps> = ({\n children,\n href,\n target,\n rel,\n onPress,\n accent = false,\n underline = false,\n size,\n color,\n style,\n testID,\n \"data-testid\": dataTestId,\n themeMode,\n themeProductContext,\n}) => {\n const inherited = useTooltipContentStyles();\n const { theme } = useResolvedTheme({ themeMode, themeProductContext });\n\n const resolvedSize = size ?? inherited?.size ?? \"md\";\n const typo = getTooltipTypoStyles(resolvedSize);\n const resolvedColor =\n color ?? inherited?.linkColor ?? theme.colors.content.brand.primary;\n const fontWeight = accent\n ? getTooltipAccentFontWeight(\n (theme as unknown as TooltipThemeTypography).typographyTokens,\n resolvedSize\n )\n : DEFAULT_BODY_FONT_WEIGHT;\n\n // Mirrors Link: never open a new tab without the reverse-tabnabbing guard.\n const resolvedRel =\n target === \"_blank\"\n ? Array.from(\n new Set([\n ...(rel ? rel.split(/\\s+/).filter(Boolean) : []),\n \"noopener\",\n \"noreferrer\",\n ])\n ).join(\" \")\n : rel;\n\n const handlePress = (event?: any) => {\n if (!onPress) return;\n event?.preventDefault?.();\n onPress();\n };\n\n return (\n <Box\n as=\"a\"\n href={href}\n target={target}\n rel={resolvedRel}\n onPress={handlePress}\n onClick={handlePress}\n role=\"link\"\n cursor=\"pointer\"\n display=\"inline-flex\"\n alignItems=\"center\"\n testID={testID}\n data-testid={dataTestId}\n hoverStyle={{ opacity: 0.8 }}\n focusStyle={{\n outlineColor: theme.colors.border.brand,\n outlineWidth: 2,\n outlineStyle: \"solid\",\n outlineOffset: 2,\n }}\n >\n <Text\n color={resolvedColor}\n fontSize={typo.fontSize}\n fontWeight={String(fontWeight)}\n textDecoration={underline ? \"underline\" : \"none\"}\n style={{ lineHeight: typo.lineHeight, ...style }}\n >\n {children}\n </Text>\n </Box>\n );\n};\n\nTooltipLink.displayName = \"TooltipLink\";\n"],"mappings":"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","names":["jsx","jsx","jsx","useResolvedTheme","jsx","useResolvedTheme","useResolvedTheme","jsx","useResolvedTheme"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsolla/xui-tooltip",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.220.0",
|
|
4
4
|
"main": "./web/index.js",
|
|
5
5
|
"module": "./web/index.mjs",
|
|
6
6
|
"types": "./web/index.d.ts",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
"test:coverage": "vitest run --coverage"
|
|
14
14
|
},
|
|
15
15
|
"dependencies": {
|
|
16
|
-
"@xsolla/xui-button": "0.
|
|
17
|
-
"@xsolla/xui-core": "0.
|
|
18
|
-
"@xsolla/xui-primitives-core": "0.
|
|
16
|
+
"@xsolla/xui-button": "0.220.0",
|
|
17
|
+
"@xsolla/xui-core": "0.220.0",
|
|
18
|
+
"@xsolla/xui-primitives-core": "0.220.0"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
21
21
|
"react": ">=16.8.0",
|
package/web/index.js
CHANGED
|
@@ -93,6 +93,10 @@ var ADDITIONAL_BLOCKED_PROPS = /* @__PURE__ */ new Set([
|
|
|
93
93
|
"fontWeight",
|
|
94
94
|
"fontFamily",
|
|
95
95
|
"textDecoration",
|
|
96
|
+
// `display` is a presentation attribute on SVG, so isPropValid lets it
|
|
97
|
+
// through — but Box consumes it purely as CSS. Without this it lands on the
|
|
98
|
+
// DOM node as a bogus `display="inline-flex"` attribute.
|
|
99
|
+
"display",
|
|
96
100
|
// Cross-platform layout prop that Text consumes as CSS, never as an
|
|
97
101
|
// attribute. Pinned explicitly because it is now spread into the styled
|
|
98
102
|
// component rather than destructured away before it can reach the DOM.
|
|
@@ -127,7 +131,7 @@ function createFilteredElement(defaultTag) {
|
|
|
127
131
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
128
132
|
var FilteredDiv = createFilteredElement("div");
|
|
129
133
|
var StyledBox = (0, import_styled_components.default)(FilteredDiv)`
|
|
130
|
-
display: flex;
|
|
134
|
+
display: ${(props) => props.display || "flex"};
|
|
131
135
|
box-sizing: border-box;
|
|
132
136
|
background-color: ${(props) => props.backgroundColor || "transparent"};
|
|
133
137
|
border-color: ${(props) => props.borderColor || "transparent"};
|
|
@@ -263,7 +267,7 @@ var Box = import_react2.default.forwardRef(
|
|
|
263
267
|
onLoad,
|
|
264
268
|
"data-testid": dataTestId || testID,
|
|
265
269
|
style: {
|
|
266
|
-
display: "block",
|
|
270
|
+
display: props.display || "block",
|
|
267
271
|
objectFit: "cover",
|
|
268
272
|
width: typeof props.width === "number" ? `${props.width}px` : props.width,
|
|
269
273
|
height: typeof props.height === "number" ? `${props.height}px` : props.height,
|