Skip to content

Commit

Permalink
fix(tooltip): Arrow not rendered in Android (#152)
Browse files Browse the repository at this point in the history
  • Loading branch information
JoseLion authored Jul 15, 2024
1 parent eeafc73 commit d7bdd12
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,8 @@ export const TourOverlay = forwardRef<TourOverlayRef, TourOverlayProps>((props,
<TooltipArrow
ref={arrowRef}
placement={placement}
position={middlewareData.arrow}
size={floating.arrow === true ? undefined : floating.arrow}
data={middlewareData.arrow}
arrow={floating.arrow === true ? undefined : floating.arrow}
/>
)}
</Animated.View>
Expand Down
157 changes: 76 additions & 81 deletions package/src/lib/components/tour-overlay/TourOverlay.styles.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { Placement } from "@floating-ui/react-native";
import { View } from "react-native";
import { RuleSet, css } from "styled-components";
import { MiddlewareData, Placement } from "@floating-ui/react-native";
import { Platform, View } from "react-native";
import { css } from "styled-components";
import styled from "styled-components/native";

import { Optional } from "../../../helpers/common";
import { vh, vw } from "../../../helpers/responsive";
import { ArrowOptions } from "../../SpotlightTour.context";

interface Position {
x?: number;
y?: number;
}

interface TooltipArrowProps {
arrow: Optional<number | ArrowOptions>;
data: Optional<MiddlewareData["arrow"]>;
placement: Placement;
position: Optional<Position>;
size: Optional<number | ArrowOptions>;
}

export const DEFAULT_ARROW: Required<ArrowOptions> = {
Expand All @@ -31,80 +26,80 @@ export const OverlayView = styled.View`

export const TooltipArrow = styled(View)<TooltipArrowProps>`
background-color: transparent;
border-color: transparent;
box-sizing: content-box;
height: 0;
position: absolute;
width: 0;
z-index: -9999;
${({ placement, position, size }) => arrowPosition({ placement, position, size })}
`;

function arrowPosition({
placement,
position = { },
size: sizeOrOption,
}: TooltipArrowProps): RuleSet {
const { x = 0, y = 0 } = position;
const { color, corner, size } = typeof sizeOrOption === "number"
? { ...DEFAULT_ARROW, size: sizeOrOption }
: { ...DEFAULT_ARROW, ...sizeOrOption };
const h = Math.sqrt(2 * size ** 2) / 2;
const height = -h + 0.5;
${({ arrow, placement, data }) => {
const { x = 0, y = 0 } = data ?? { };
const { color, corner, size } = typeof arrow === "number"
? { ...DEFAULT_ARROW, size: arrow }
: { ...DEFAULT_ARROW, ...arrow };
// Android cannot apply specific border + radius:
// https://github.com/facebook/react-native/issues/9262
const radius = Platform.OS === "android" ? 0 : corner;
const h = Math.sqrt(2 * size ** 2) / 2;
const height = -h + 0.5;
switch (placement) {
case "bottom":
case "bottom-end":
case "bottom-start":
return css`
border-bottom-width: ${size}px;
border-left-color: ${color.toString()};
border-left-width: ${size}px;
border-top-left-radius: ${corner}px;
left: ${x + h}px;
top: ${height}px;
transform: rotate(45deg);
transform-origin: top left;
`;
case "left":
case "left-end":
case "left-start":
return css`
border-bottom-width: ${size}px;
border-right-color: ${color.toString()};
border-right-width: ${size}px;
border-top-right-radius: ${corner}px;
right: ${height}px;
top: ${y + h}px;
transform: rotate(45deg);
transform-origin: top right;
`;
case "right":
case "right-end":
case "right-start":
return css`
border-bottom-left-radius: ${corner}px;
border-left-color: ${color.toString()};
border-left-width: ${size}px;
border-top-width: ${size}px;
bottom: ${y + h}px;
left: ${height}px;
transform: rotate(45deg);
transform-origin: bottom left;
`;
case "top":
case "top-end":
case "top-start":
return css`
border-bottom-left-radius: ${corner}px;
border-left-color: ${color.toString()};
border-left-width: ${size}px;
border-top-width: ${size}px;
bottom: ${height}px;
left: ${x + h}px;
transform: rotate(-45deg);
transform-origin: bottom left;
`;
}
}
switch (placement) {
case "bottom":
case "bottom-end":
case "bottom-start":
return css`
border-bottom-color: transparent;
border-bottom-width: ${size}px;
border-left-color: ${color.toString()};
border-left-width: ${size}px;
border-top-left-radius: ${radius}px;
left: ${x + h}px;
top: ${height}px;
transform: rotate(45deg);
transform-origin: top left;
`;
case "left":
case "left-end":
case "left-start":
return css`
border-bottom-color: transparent;
border-bottom-width: ${size}px;
border-right-color: ${color.toString()};
border-right-width: ${size}px;
border-top-right-radius: ${radius}px;
right: ${height}px;
top: ${y + h}px;
transform: rotate(45deg);
transform-origin: top right;
`;
case "right":
case "right-end":
case "right-start":
return css`
border-bottom-color: transparent;
border-bottom-width: ${size}px;
border-left-color: ${color.toString()};
border-left-width: ${size}px;
border-top-left-radius: ${radius}px;
left: ${height}px;
top: ${y + h}px;
transform: rotate(-45deg);
transform-origin: top left;
`;
case "top":
case "top-end":
case "top-start":
return css`
border-bottom-color: ${color.toString()};
border-bottom-left-radius: ${radius}px;
border-bottom-width: ${size}px;
border-left-color: ${color.toString()};
border-right-color: transparent;
border-right-width: ${size}px;
bottom: ${height}px;
left: ${x + h}px;
transform: rotate(-45deg);
transform-origin: bottom left;
`;
}
}}
`;

0 comments on commit d7bdd12

Please sign in to comment.