import React, { useMemo, useContext, useEffect } from "react";
import { ImageStyle, StyleSheet, View, ViewStyle } from "react-native";
import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
import { MeasurementPortalContext } from "../../../MeasurmentsPortal/MeasurementsPortal";
type BorderPosition = "inside" | "outside" | "center";
interface Props {
hasFocusableInside: (entry: ZappEntry) => boolean;
entry: ZappEntry;
state: CellState;
hasTextLabels: boolean;
style: ImageStyle | ViewStyle;
borderPosition: BorderPosition;
borderPaddingTop: number;
borderPaddingRight: number;
borderPaddingBottom: number;
borderPaddingLeft: number;
children: React.ReactNode;
}
const COLOR_TRANSPARENT = "transparent";
const styles = StyleSheet.create({
container: {
overflow: "visible",
borderWidth: 0,
borderColor: COLOR_TRANSPARENT,
},
border: {
...StyleSheet.absoluteFillObject,
zIndex: 1,
},
});
export const getBorderPadding = (
borderPosition: BorderPosition,
borderWidth: number
) => {
switch (borderPosition) {
case "inside":
return 0;
case "center":
return borderWidth / 2;
case "outside":
return borderWidth;
default:
return borderWidth;
}
};
const Border = ({
style,
padding,
borderPosition,
}: {
style: ViewStyle;
padding: ViewStyle;
borderPosition: BorderPosition;
}) => {
if (!borderPosition) {
return null;
}
const borderWidth = toNumberWithDefaultZero(style.borderWidth);
const containerPadding = getBorderPadding(borderPosition, borderWidth);
const initialBorderRadius = toNumberWithDefaultZero(style.borderRadius);
const paddingTop = toNumberWithDefaultZero(padding.paddingTop);
const paddingRight = toNumberWithDefaultZero(padding.paddingRight);
const paddingBottom = toNumberWithDefaultZero(padding.paddingBottom);
const paddingLeft = toNumberWithDefaultZero(padding.paddingLeft);
const borderRadiusStyle = initialBorderRadius
? {
borderTopLeftRadius:
initialBorderRadius +
containerPadding +
Math.min(paddingTop, paddingLeft),
borderTopRightRadius:
initialBorderRadius +
containerPadding +
Math.min(paddingTop, paddingRight),
borderBottomLeftRadius:
initialBorderRadius +
containerPadding +
Math.min(paddingBottom, paddingLeft),
borderBottomRightRadius:
initialBorderRadius +
containerPadding +
Math.min(paddingBottom, paddingRight),
}
: {
borderTopLeftRadius: 0,
borderTopRightRadius: 0,
borderBottomLeftRadius: 0,
borderBottomRightRadius: 0,
};
return (
);
};
export const BorderContainerView = (props: Props) => {
const {
borderPosition,
borderPaddingTop,
borderPaddingRight,
borderPaddingBottom,
borderPaddingLeft,
style,
children,
hasFocusableInside,
entry,
state,
hasTextLabels,
} = props;
const accessibilityManager = useAccessibilityManager();
const isMeasurement = useContext(MeasurementPortalContext);
const isImageOnlyCell = useMemo(
() =>
!hasFocusableInside(entry) &&
!hasTextLabels &&
state === "focused" &&
!isMeasurement?.measuringInProgress,
[
hasFocusableInside,
entry,
hasTextLabels,
state,
isMeasurement?.measuringInProgress,
]
);
useEffect(() => {
if (isImageOnlyCell && entry?.title) {
accessibilityManager.addHeading(String(entry.title));
}
}, [isImageOnlyCell, entry?.title]);
const padding =
borderPosition === "outside"
? {
paddingTop: borderPaddingTop,
paddingRight: borderPaddingRight,
paddingBottom: borderPaddingBottom,
paddingLeft: borderPaddingLeft,
}
: {};
return (
{children}
);
};