diff --git a/package/src/lib/components/tour-overlay/TourOverlay.component.tsx b/package/src/lib/components/tour-overlay/TourOverlay.component.tsx index b293ff5..c75742e 100644 --- a/package/src/lib/components/tour-overlay/TourOverlay.component.tsx +++ b/package/src/lib/components/tour-overlay/TourOverlay.component.tsx @@ -229,8 +229,8 @@ export const TourOverlay = forwardRef((props, )} diff --git a/package/src/lib/components/tour-overlay/TourOverlay.styles.ts b/package/src/lib/components/tour-overlay/TourOverlay.styles.ts index 3ad61ed..0dc093a 100644 --- a/package/src/lib/components/tour-overlay/TourOverlay.styles.ts +++ b/package/src/lib/components/tour-overlay/TourOverlay.styles.ts @@ -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; + data: Optional; placement: Placement; - position: Optional; - size: Optional; } export const DEFAULT_ARROW: Required = { @@ -31,80 +26,80 @@ export const OverlayView = styled.View` export const TooltipArrow = styled(View)` 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; + `; + } + }} +`;