UNPKG

@metamask/design-system-react-native

Version:
90 lines 3.78 kB
function $importDefault(module) { if (module?.__esModule) { return module.default; } return module; } import { useTailwind } from "@metamask/design-system-twrnc-preset"; import $React, { useCallback, useState, useMemo } from "react"; const React = $importDefault($React); import { View } from "react-native/index.js"; import { BadgeWrapperPosition, BadgeWrapperPositionAnchorShape } from "../../types/index.mjs"; export const BadgeWrapper = ({ children, childrenContainerProps, badge, badgeContainerProps, position = BadgeWrapperPosition.BottomRight, positionAnchorShape = BadgeWrapperPositionAnchorShape.Circular, positionXOffset = 0, positionYOffset = 0, customPosition, twClassName = '', style, ...props }) => { const tw = useTailwind(); const [anchorWidth, setAnchorWidth] = useState(0); const [anchorHeight, setAnchorHeight] = useState(0); const [badgeWidth, setbadgeWidth] = useState(0); const [badgeHeight, setbadgeHeight] = useState(0); // Fetching the dimensions of the anchor and bagde element to properly position the badge const getAnchorSize = useCallback((event) => { const { width, height } = event.nativeEvent.layout; setAnchorWidth(width); setAnchorHeight(height); }, []); const getBadgeSize = useCallback((event) => { const { width, height } = event.nativeEvent.layout; setbadgeWidth(width); setbadgeHeight(height); }, []); const finalPositions = useMemo(() => { if (customPosition) { return customPosition; } // 0.1464 is a mathematical coeeficient to move // from a 0,0 corner of a rectangular shape to the closest "corner" // of a circular shape anchor element const anchorShapeXOffset = positionAnchorShape === BadgeWrapperPositionAnchorShape.Rectangular ? 0 : anchorWidth * 0.1464; const anchorShapeYOffset = positionAnchorShape === BadgeWrapperPositionAnchorShape.Rectangular ? 0 : anchorHeight * 0.1464; // This is to center the badge in the corner of the anchor element const badgeCenteringXOffset = badgeWidth / 2; const badgeCenteringYOffset = badgeHeight / 2; const finalXOffset = anchorShapeXOffset - badgeCenteringXOffset + positionXOffset; const finalYOffset = anchorShapeYOffset - badgeCenteringYOffset + positionYOffset; switch (position) { case BadgeWrapperPosition.TopRight: return { top: finalYOffset, right: finalXOffset, }; case BadgeWrapperPosition.BottomLeft: return { bottom: finalYOffset, left: finalXOffset, }; case BadgeWrapperPosition.TopLeft: return { top: finalYOffset, left: finalXOffset, }; case BadgeWrapperPosition.BottomRight: default: return { bottom: finalYOffset, right: finalXOffset, }; } }, [ position, positionAnchorShape, anchorWidth, anchorHeight, badgeWidth, badgeHeight, positionXOffset, positionYOffset, customPosition, ]); return (<View style={[tw `relative self-start ${twClassName}`, style]} {...props}> <View onLayout={getAnchorSize} {...childrenContainerProps}> {children} </View> <View onLayout={getBadgeSize} style={[tw `absolute`, { ...finalPositions }]} {...badgeContainerProps}> {badge} </View> </View>); }; //# sourceMappingURL=BadgeWrapper.mjs.map